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