Use verifyNoRedirect instead of calling the request handler directly
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / web / pages / OptionsPageTest.kt
1 package net.pterodactylus.sone.web.pages
2
3 import net.pterodactylus.sone.data.SoneOptions.DefaultSoneOptions
4 import net.pterodactylus.sone.data.SoneOptions.LoadExternalContent.FOLLOWED
5 import net.pterodactylus.sone.data.SoneOptions.LoadExternalContent.TRUSTED
6 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.ALWAYS
7 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.NO
8 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.WRITING
9 import net.pterodactylus.sone.test.whenever
10 import net.pterodactylus.util.web.Method.POST
11 import org.hamcrest.MatcherAssert.assertThat
12 import org.hamcrest.Matchers.equalTo
13 import org.hamcrest.Matchers.hasItem
14 import org.hamcrest.Matchers.nullValue
15 import org.junit.Before
16 import org.junit.Test
17
18 /**
19  * Unit test for [OptionsPage].
20  */
21 class OptionsPageTest : WebPageTest() {
22
23         private val page = OptionsPage(template, webInterface)
24
25         override fun getPage() = page
26
27         @Before
28         fun setupPreferences() {
29                 core.preferences.insertionDelay = 1
30                 core.preferences.charactersPerPost = 50
31                 core.preferences.fcpFullAccessRequired = WRITING
32                 core.preferences.imagesPerPage = 4
33                 core.preferences.isFcpInterfaceActive = true
34                 core.preferences.isRequireFullAccess = true
35                 core.preferences.negativeTrust = 7
36                 core.preferences.positiveTrust = 8
37                 core.preferences.postCutOffLength = 51
38                 core.preferences.postsPerPage = 10
39                 core.preferences.trustComment = "11"
40         }
41
42         @Before
43         fun setupSoneOptions() {
44                 whenever(currentSone.options).thenReturn(DefaultSoneOptions().apply {
45                         isAutoFollow = true
46                         isShowNewPostNotifications = true
47                         isShowNewReplyNotifications = true
48                         isShowNewSoneNotifications = true
49                         isSoneInsertNotificationEnabled = true
50                         loadLinkedImages = FOLLOWED
51                         showCustomAvatars = FOLLOWED
52                 })
53         }
54
55         @Test
56         fun `get request stores all preferences in the template context`() {
57                 verifyNoRedirect {
58                         assertThat(templateContext["auto-follow"], equalTo<Any>(true))
59                         assertThat(templateContext["show-notification-new-sones"], equalTo<Any>(true))
60                         assertThat(templateContext["show-notification-new-posts"], equalTo<Any>(true))
61                         assertThat(templateContext["show-notification-new-replies"], equalTo<Any>(true))
62                         assertThat(templateContext["enable-sone-insert-notifications"], equalTo<Any>(true))
63                         assertThat(templateContext["load-linked-images"], equalTo<Any>("FOLLOWED"))
64                         assertThat(templateContext["show-custom-avatars"], equalTo<Any>("FOLLOWED"))
65                         assertThat(templateContext["insertion-delay"], equalTo<Any>(1))
66                         assertThat(templateContext["characters-per-post"], equalTo<Any>(50))
67                         assertThat(templateContext["fcp-full-access-required"], equalTo<Any>(1))
68                         assertThat(templateContext["images-per-page"], equalTo<Any>(4))
69                         assertThat(templateContext["fcp-interface-active"], equalTo<Any>(true))
70                         assertThat(templateContext["require-full-access"], equalTo<Any>(true))
71                         assertThat(templateContext["negative-trust"], equalTo<Any>(7))
72                         assertThat(templateContext["positive-trust"], equalTo<Any>(8))
73                         assertThat(templateContext["post-cut-off-length"], equalTo<Any>(51))
74                         assertThat(templateContext["posts-per-page"], equalTo<Any>(10))
75                         assertThat(templateContext["trust-comment"], equalTo<Any>("11"))
76                 }
77         }
78
79         @Test
80         fun `get request without sone does not store sone-specific preferences in the template context`() {
81                 unsetCurrentSone()
82                 verifyNoRedirect {
83                         assertThat(templateContext["auto-follow"], nullValue())
84                         assertThat(templateContext["show-notification-new-sones"], nullValue())
85                         assertThat(templateContext["show-notification-new-posts"], nullValue())
86                         assertThat(templateContext["show-notification-new-replies"], nullValue())
87                         assertThat(templateContext["enable-sone-insert-notifications"], nullValue())
88                         assertThat(templateContext["load-linked-images"], nullValue())
89                         assertThat(templateContext["show-custom-avatars"], nullValue())
90                 }
91         }
92
93         private fun <T> verifyThatOptionCanBeSet(option: String, setValue: Any?, expectedValue: T, getter: () -> T) {
94                 setMethod(POST)
95                 addHttpRequestPart("show-custom-avatars", "ALWAYS")
96                 addHttpRequestPart("load-linked-images", "ALWAYS")
97                 addHttpRequestPart(option, setValue.toString())
98                 verifyRedirect("options.html") {
99                         assertThat(getter(), equalTo(expectedValue))
100                 }
101         }
102
103         @Test
104         fun `auto-follow option can be set`() {
105                 verifyThatOptionCanBeSet("auto-follow", "checked", true) { currentSone.options.isAutoFollow }
106         }
107
108         @Test
109         fun `show new sone notification option can be set`() {
110                 verifyThatOptionCanBeSet("show-notification-new-sones", "checked", true) { currentSone.options.isShowNewSoneNotifications }
111         }
112
113         @Test
114         fun `show new post notification option can be set`() {
115                 verifyThatOptionCanBeSet("show-notification-new-posts", "checked", true) { currentSone.options.isShowNewPostNotifications }
116         }
117
118         @Test
119         fun `show new reply notification option can be set`() {
120                 verifyThatOptionCanBeSet("show-notification-new-replies", "checked", true) { currentSone.options.isShowNewReplyNotifications }
121         }
122
123         @Test
124         fun `enable sone insert notifications option can be set`() {
125                 verifyThatOptionCanBeSet("enable-sone-insert-notifications", "checked", true) { currentSone.options.isSoneInsertNotificationEnabled }
126         }
127
128         @Test
129         fun `load linked images option can be set`() {
130                 verifyThatOptionCanBeSet("load-linked-images", "TRUSTED", TRUSTED) { currentSone.options.loadLinkedImages }
131         }
132
133         @Test
134         fun `show custom avatar option can be set`() {
135                 verifyThatOptionCanBeSet("show-custom-avatars", "TRUSTED", TRUSTED) { currentSone.options.showCustomAvatars }
136         }
137
138         private fun verifyThatWrongValueForPreferenceIsDetected(name: String, value: String) {
139                 unsetCurrentSone()
140                 setMethod(POST)
141                 addHttpRequestPart(name, value)
142                 verifyNoRedirect {
143                         assertThat(templateContext["fieldErrors"] as Iterable<*>, hasItem(name))
144                 }
145         }
146
147         private fun <T> verifyThatPreferencesCanBeSet(name: String, setValue: String?, expectedValue: T, getter: () -> T) {
148                 unsetCurrentSone()
149                 setMethod(POST)
150                 addHttpRequestPart(name, setValue)
151                 verifyRedirect("options.html") {
152                         assertThat(getter(), equalTo(expectedValue))
153                 }
154         }
155
156         @Test
157         fun `insertion delay can not be set to less than 0 seconds`() {
158                 verifyThatWrongValueForPreferenceIsDetected("insertion-delay", "-1")
159         }
160
161         @Test
162         fun `insertion delay can be set to 0 seconds`() {
163                 verifyThatPreferencesCanBeSet("insertion-delay", "0", 0) { core.preferences.insertionDelay }
164         }
165
166         @Test
167         fun `setting insertion to an invalid value will reset it`() {
168                 verifyThatPreferencesCanBeSet("insertion-delay", "foo", 60) { core.preferences.insertionDelay }
169         }
170
171         @Test
172         fun `characters per post can not be set to less than -1`() {
173                 verifyThatWrongValueForPreferenceIsDetected("characters-per-post", "-2")
174         }
175
176         @Test
177         fun `characters per post can be set to -1`() {
178                 verifyThatPreferencesCanBeSet("characters-per-post", "-1", -1) { core.preferences.charactersPerPost }
179         }
180
181         @Test
182         fun `characters per post can not be set to 0`() {
183                 verifyThatWrongValueForPreferenceIsDetected("characters-per-post", "0")
184         }
185
186         @Test
187         fun `characters per post can not be set to 49`() {
188                 verifyThatWrongValueForPreferenceIsDetected("characters-per-post", "49")
189         }
190
191         @Test
192         fun `characters per post can be set to 50`() {
193                 verifyThatPreferencesCanBeSet("characters-per-post", "50", 50) { core.preferences.charactersPerPost }
194         }
195
196         @Test
197         fun `fcp full acess required option can be set to always`() {
198                 verifyThatPreferencesCanBeSet("fcp-full-access-required", "2", ALWAYS) { core.preferences.fcpFullAccessRequired }
199         }
200
201         @Test
202         fun `fcp full acess required option can be set to writing`() {
203                 verifyThatPreferencesCanBeSet("fcp-full-access-required", "1", WRITING) { core.preferences.fcpFullAccessRequired }
204         }
205
206         @Test
207         fun `fcp full acess required option can be set to no`() {
208                 verifyThatPreferencesCanBeSet("fcp-full-access-required", "0", NO) { core.preferences.fcpFullAccessRequired }
209         }
210
211         @Test
212         fun `fcp full acess required option is not changed if invalid value is set`() {
213                 verifyThatPreferencesCanBeSet("fcp-full-access-required", "foo", WRITING) { core.preferences.fcpFullAccessRequired }
214         }
215
216         @Test
217         fun `images per page can not be set to 0`() {
218                 verifyThatWrongValueForPreferenceIsDetected("images-per-page", "0")
219         }
220
221         @Test
222         fun `images per page can be set to 1`() {
223                 verifyThatPreferencesCanBeSet("images-per-page", "1", 1) { core.preferences.imagesPerPage }
224         }
225
226         @Test
227         fun `images per page is set to 9 if invalid value is requested`() {
228                 verifyThatPreferencesCanBeSet("images-per-page", "foo", 9) { core.preferences.imagesPerPage }
229         }
230
231         @Test
232         fun `fcp interface can be set to true`() {
233                 verifyThatPreferencesCanBeSet("fcp-interface-active", "checked", true) { core.preferences.isFcpInterfaceActive }
234         }
235
236         @Test
237         fun `fcp interface can be set to false`() {
238                 verifyThatPreferencesCanBeSet("fcp-interface-active", null, false) { core.preferences.isFcpInterfaceActive }
239         }
240
241         @Test
242         fun `require full access can be set to true`() {
243                 verifyThatPreferencesCanBeSet("require-full-access", "checked", true) { core.preferences.isRequireFullAccess }
244         }
245
246         @Test
247         fun `require full access can be set to false`() {
248                 verifyThatPreferencesCanBeSet("require-full-access", null, false) { core.preferences.isRequireFullAccess }
249         }
250
251         @Test
252         fun `negative trust can not be set to -101`() {
253                 verifyThatWrongValueForPreferenceIsDetected("negative-trust", "-101")
254         }
255
256         @Test
257         fun `negative trust can be set to -100`() {
258                 verifyThatPreferencesCanBeSet("negative-trust", "-100", -100) { core.preferences.negativeTrust }
259         }
260
261         @Test
262         fun `negative trust can be set to 100`() {
263                 verifyThatPreferencesCanBeSet("negative-trust", "100", 100) { core.preferences.negativeTrust }
264         }
265
266         @Test
267         fun `negative trust can not be set to 101`() {
268                 verifyThatWrongValueForPreferenceIsDetected("negative-trust", "101")
269         }
270
271         @Test
272         fun `negative trust is set to default on invalid value`() {
273                 verifyThatPreferencesCanBeSet("negative-trust", "invalid", -25) { core.preferences.negativeTrust }
274         }
275
276         @Test
277         fun `positive trust can not be set to -1`() {
278                 verifyThatWrongValueForPreferenceIsDetected("positive-trust", "-1")
279         }
280
281         @Test
282         fun `positive trust can be set to 0`() {
283                 verifyThatPreferencesCanBeSet("positive-trust", "0", 0) { core.preferences.positiveTrust }
284         }
285
286         @Test
287         fun `positive trust can be set to 100`() {
288                 verifyThatPreferencesCanBeSet("positive-trust", "100", 100) { core.preferences.positiveTrust }
289         }
290
291         @Test
292         fun `positive trust can not be set to 101`() {
293                 verifyThatWrongValueForPreferenceIsDetected("positive-trust", "101")
294         }
295
296         @Test
297         fun `positive trust is set to default on invalid value`() {
298                 verifyThatPreferencesCanBeSet("positive-trust", "invalid", 75) { core.preferences.positiveTrust }
299         }
300
301         @Test
302         fun `post cut off length can not be set to -49`() {
303                 verifyThatWrongValueForPreferenceIsDetected("post-cut-off-length", "-49")
304         }
305
306         @Test
307         fun `post cut off length can be set to 50`() {
308                 verifyThatPreferencesCanBeSet("post-cut-off-length", "50", 50) { core.preferences.postCutOffLength }
309         }
310
311         @Test
312         fun `post cut off length is set to default on invalid value`() {
313                 verifyThatPreferencesCanBeSet("post-cut-off-length", "invalid", 200) { core.preferences.postCutOffLength }
314         }
315
316         @Test
317         fun `posts per page can not be set to 0`() {
318                 verifyThatWrongValueForPreferenceIsDetected("posts-per-page", "-49")
319         }
320
321         @Test
322         fun `posts per page can be set to 1`() {
323                 verifyThatPreferencesCanBeSet("posts-per-page", "1", 1) { core.preferences.postsPerPage }
324         }
325
326         @Test
327         fun `posts per page is set to default on invalid value`() {
328                 verifyThatPreferencesCanBeSet("posts-per-page", "invalid", 10) { core.preferences.postsPerPage }
329         }
330
331         @Test
332         fun `trust comment can be set`() {
333                 verifyThatPreferencesCanBeSet("trust-comment", "trust", "trust") { core.preferences.trustComment }
334         }
335
336         @Test
337         fun `trust comment is set to default when set to empty value`() {
338                 verifyThatPreferencesCanBeSet("trust-comment", "", "Set from Sone Web Interface") { core.preferences.trustComment }
339         }
340
341 }