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