🔀 Merge branch 'release/v82'
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / core / PreferencesTest.kt
1 package net.pterodactylus.sone.core
2
3 import com.google.common.eventbus.EventBus
4 import com.google.common.eventbus.Subscribe
5 import net.pterodactylus.sone.core.event.InsertionDelayChangedEvent
6 import net.pterodactylus.sone.core.event.StrictFilteringActivatedEvent
7 import net.pterodactylus.sone.core.event.StrictFilteringDeactivatedEvent
8 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired
9 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.ALWAYS
10 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.NO
11 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.WRITING
12 import net.pterodactylus.sone.fcp.event.FcpInterfaceActivatedEvent
13 import net.pterodactylus.sone.fcp.event.FcpInterfaceDeactivatedEvent
14 import net.pterodactylus.sone.fcp.event.FullAccessRequiredChanged
15 import net.pterodactylus.util.config.Configuration
16 import net.pterodactylus.util.config.MapConfigurationBackend
17 import org.hamcrest.Matcher
18 import org.hamcrest.MatcherAssert.assertThat
19 import org.hamcrest.Matchers.emptyIterable
20 import org.hamcrest.Matchers.equalTo
21 import org.hamcrest.Matchers.hasItem
22 import org.hamcrest.Matchers.instanceOf
23 import org.hamcrest.Matchers.nullValue
24 import org.junit.Test
25
26 /**
27  * Unit test for [Preferences].
28  */
29 class PreferencesTest {
30
31         private val eventBus = EventBus()
32         private val preferences = Preferences(eventBus)
33
34         @Test
35         fun `preferences retain insertion delay`() {
36                 preferences.newInsertionDelay = 15
37                 assertThat(preferences.insertionDelay, equalTo(15))
38         }
39
40         @Test
41         fun `preferences sends event on setting insertion delay`() {
42                 val events = mutableListOf<InsertionDelayChangedEvent>()
43                 eventBus.register(object {
44                         @Subscribe
45                         fun insertionDelayChangedEvent(event: InsertionDelayChangedEvent) =
46                                         events.add(event)
47                 })
48                 preferences.newInsertionDelay = 15
49                 assertThat(events, hasItem(InsertionDelayChangedEvent(15)))
50         }
51
52         @Test(expected = IllegalArgumentException::class)
53         fun `invalid insertion delay is rejected`() {
54                 preferences.newInsertionDelay = -15
55         }
56
57         @Test
58         fun `no event is sent when invalid insertion delay is set`() {
59                 val events = mutableListOf<InsertionDelayChangedEvent>()
60                 eventBus.register(object {
61                         @Subscribe
62                         fun insertionDelayChanged(event: InsertionDelayChangedEvent) =
63                                         events.add(event)
64                 })
65                 try {
66                         preferences.newInsertionDelay = -15
67                 } catch (iae: IllegalArgumentException) {
68                         /* ignore. */
69                 }
70
71                 assertThat(events, emptyIterable())
72         }
73
74         @Test
75         fun `preferences return default value when insertion delay is set to null`() {
76                 preferences.newInsertionDelay = null
77                 assertThat(preferences.insertionDelay, equalTo(60))
78         }
79
80         @Test
81         fun `preferences start with insertion delay default value`() {
82                 assertThat(preferences.insertionDelay, equalTo(60))
83         }
84
85         @Test
86         fun `preferences saves null for default insertion delay setting`() {
87                 verifySavedOption(nullValue()) { it.getIntValue("Option/InsertionDelay").getValue(null) }
88         }
89
90         @Test
91         fun `preferences retain posts per page`() {
92                 preferences.newPostsPerPage = 15
93                 assertThat(preferences.postsPerPage, equalTo(15))
94         }
95
96         @Test(expected = IllegalArgumentException::class)
97         fun `invalid posts per page is rejected`() {
98                 preferences.newPostsPerPage = -15
99         }
100
101         @Test
102         fun `preferences return default value when posts per page is set to null`() {
103                 preferences.newPostsPerPage = null
104                 assertThat(preferences.postsPerPage, equalTo(10))
105         }
106
107         @Test
108         fun `preferences start with posts per page default value`() {
109                 assertThat(preferences.postsPerPage, equalTo(10))
110         }
111
112         @Test
113         fun `preferences retain images per page`() {
114                 preferences.newImagesPerPage = 15
115                 assertThat(preferences.imagesPerPage, equalTo(15))
116         }
117
118         @Test(expected = IllegalArgumentException::class)
119         fun `invalid images per page is rejected`() {
120                 preferences.newImagesPerPage = -15
121         }
122
123         @Test
124         fun `preferences return default value when images per page is set to null`() {
125                 preferences.newImagesPerPage = null
126                 assertThat(preferences.imagesPerPage, equalTo(9))
127         }
128
129         @Test
130         fun `preferences start with images per page default value`() {
131                 assertThat(preferences.imagesPerPage, equalTo(9))
132         }
133
134         @Test
135         fun `preferences retain characters per post`() {
136                 preferences.newCharactersPerPost = 150
137                 assertThat(preferences.charactersPerPost, equalTo(150))
138         }
139
140         @Test(expected = IllegalArgumentException::class)
141         fun `invalid characters per post is rejected`() {
142                 preferences.newCharactersPerPost = -15
143         }
144
145         @Test
146         fun `preferences return default value when characters per post is set to null`() {
147                 preferences.newCharactersPerPost = null
148                 assertThat(preferences.charactersPerPost, equalTo(400))
149         }
150
151         @Test
152         fun `preferences start with characters per post default value`() {
153                 assertThat(preferences.charactersPerPost, equalTo(400))
154         }
155
156         @Test
157         fun `preferences retain post cut off length`() {
158                 preferences.newPostCutOffLength = 150
159                 assertThat(preferences.postCutOffLength, equalTo(150))
160         }
161
162         @Test(expected = IllegalArgumentException::class)
163         fun `invalid post cut off length is rejected`() {
164                 preferences.newPostCutOffLength = -15
165         }
166
167         @Test(expected = IllegalArgumentException::class)
168         fun `cut off length of minus one is not allowed`() {
169                 preferences.newPostCutOffLength = -1
170         }
171
172         @Test
173         fun `preferences return default value when post cut off length is set to null`() {
174                 preferences.newPostCutOffLength = null
175                 assertThat(preferences.postCutOffLength, equalTo(200))
176         }
177
178         @Test
179         fun `preferences start with post cut off length default value`() {
180                 assertThat(preferences.postCutOffLength, equalTo(200))
181         }
182
183         @Test
184         fun `preferences retain require full access of true`() {
185                 preferences.newRequireFullAccess = true
186                 assertThat(preferences.requireFullAccess, equalTo(true))
187         }
188
189         @Test
190         fun `preferences retain require full access of false`() {
191                 preferences.newRequireFullAccess = false
192                 assertThat(preferences.requireFullAccess, equalTo(false))
193         }
194
195         @Test
196         fun `preferences return default value when require full access is set to null`() {
197                 preferences.newRequireFullAccess = null
198                 assertThat(preferences.requireFullAccess, equalTo(false))
199         }
200
201         @Test
202         fun `preferences start with require full access default value`() {
203                 assertThat(preferences.requireFullAccess, equalTo(false))
204         }
205
206         @Test
207         fun `preferences retain fcp interface active of true`() {
208                 val events = mutableListOf<FcpInterfaceActivatedEvent>()
209                 eventBus.register(object {
210                         @Subscribe
211                         fun fcpInterfaceActivatedEvent(event: FcpInterfaceActivatedEvent) =
212                                         events.add(event)
213                 })
214                 preferences.newFcpInterfaceActive = true
215                 assertThat(preferences.fcpInterfaceActive, equalTo(true))
216                 assertThat(events, hasItem<FcpInterfaceActivatedEvent>(instanceOf(FcpInterfaceActivatedEvent::class.java)))
217         }
218
219         @Test
220         fun `preferences retain fcp interface active of false`() {
221                 val events = mutableListOf<FcpInterfaceDeactivatedEvent>()
222                 eventBus.register(object {
223                         @Subscribe
224                         fun fcpInterfaceDeactivatedEvent(event: FcpInterfaceDeactivatedEvent) =
225                                         events.add(event)
226                 })
227                 preferences.newFcpInterfaceActive = false
228                 assertThat(preferences.fcpInterfaceActive, equalTo(false))
229                 assertThat(events, hasItem<FcpInterfaceDeactivatedEvent>(instanceOf(FcpInterfaceDeactivatedEvent::class.java)))
230         }
231
232         @Test
233         fun `preferences return default value when fcp interface active is set to null`() {
234                 val events = mutableListOf<FcpInterfaceDeactivatedEvent>()
235                 eventBus.register(object {
236                         @Subscribe
237                         fun fcpInterfaceDeactivatedEvent(event: FcpInterfaceDeactivatedEvent) =
238                                         events.add(event)
239                 })
240                 preferences.newFcpInterfaceActive = null
241                 assertThat(preferences.fcpInterfaceActive, equalTo(false))
242                 assertThat(events, hasItem<FcpInterfaceDeactivatedEvent>(instanceOf(FcpInterfaceDeactivatedEvent::class.java)))
243         }
244
245         @Test
246         fun `preferences start with fcp interface active default value`() {
247                 assertThat(preferences.fcpInterfaceActive, equalTo(false))
248         }
249
250         @Test
251         fun `preferences retain fcp full access required of no`() {
252                 verifyFullAccessRequiredChangedEvent(NO)
253         }
254
255         private fun verifyFullAccessRequiredChangedEvent(set: FullAccessRequired?, expected: FullAccessRequired = set!!) {
256                 val events = mutableListOf<FullAccessRequiredChanged>()
257                 eventBus.register(object {
258                         @Subscribe
259                         fun fullAccessRequiredChanged(event: FullAccessRequiredChanged) =
260                                         events.add(event)
261                 })
262                 preferences.newFcpFullAccessRequired = set
263                 assertThat(preferences.fcpFullAccessRequired, equalTo(expected))
264                 assertThat(events.single().fullAccessRequired, equalTo(expected))
265         }
266
267         @Test
268         fun `preferences retain fcp full access required of writing`() {
269                 verifyFullAccessRequiredChangedEvent(WRITING)
270         }
271
272         @Test
273         fun `preferences retain fcp full access required of always`() {
274                 verifyFullAccessRequiredChangedEvent(ALWAYS)
275         }
276
277         @Test
278         fun `preferences return default value when fcp full access required is set to null`() {
279                 verifyFullAccessRequiredChangedEvent(null, ALWAYS)
280         }
281
282         @Test
283         fun `preferences start with fcp full access required default value`() {
284                 assertThat(preferences.fcpFullAccessRequired, equalTo(ALWAYS))
285         }
286
287         @Test
288         fun `setting insertion delay to valid value sends change event`() {
289                 testPreferencesChangedEvent("InsertionDelay", { preferences.newInsertionDelay = it }, 30)
290         }
291
292         @Test
293         fun `setting posts per page to valid value sends change event`() {
294                 testPreferencesChangedEvent("PostsPerPage", { preferences.newPostsPerPage = it }, 31)
295         }
296
297         @Test
298         fun `default strict filtering is false`() {
299                 assertThat(preferences.strictFiltering, equalTo(false))
300         }
301
302         @Test
303         fun `strict filtering can be set`() {
304                 preferences.newStrictFiltering = true
305                 assertThat(preferences.strictFiltering, equalTo(true))
306         }
307
308         @Test
309         fun `strict filtering returns to default on null`() {
310                 preferences.newStrictFiltering = true
311                 preferences.newStrictFiltering = null
312                 assertThat(preferences.strictFiltering, equalTo(false))
313         }
314
315         @Test
316         fun `event is generated when strict filtering is activated`() {
317                 val events = mutableListOf<StrictFilteringActivatedEvent>()
318                 eventBus.register(object {
319                         @Subscribe fun strictFilteringActivatedEvent(event: StrictFilteringActivatedEvent) =
320                                         events.add(event)
321                 })
322                 preferences.newStrictFiltering = true
323                 assertThat(events, hasItem<StrictFilteringActivatedEvent>(instanceOf(StrictFilteringActivatedEvent::class.java)))
324         }
325
326         @Test
327         fun `event is generated when strict filtering is deactivated`() {
328                 val events = mutableListOf<StrictFilteringDeactivatedEvent>()
329                 eventBus.register(object {
330                         @Subscribe fun strictFilteringDeactivatedEvent(event: StrictFilteringDeactivatedEvent) =
331                                         events.add(event)
332                 })
333                 preferences.newStrictFiltering = false
334                 assertThat(events, hasItem<StrictFilteringDeactivatedEvent>(instanceOf(StrictFilteringDeactivatedEvent::class.java)))
335         }
336
337         @Test
338         fun `default strict filtering is saved as null`() {
339                 verifySavedOption(nullValue()) { it.getBooleanValue("Option/StrictFiltering").value }
340         }
341
342         @Test
343         fun `activated strict filtering is saved as true`() {
344                 preferences.newStrictFiltering = true
345                 verifySavedOption(equalTo(true)) { it.getBooleanValue("Option/StrictFiltering").value }
346         }
347
348         @Test
349         fun `deactivated strict filtering is saved as false`() {
350                 preferences.newStrictFiltering = false
351                 verifySavedOption(equalTo(false)) { it.getBooleanValue("Option/StrictFiltering").value }
352         }
353
354         private fun <T> verifySavedOption(matcher: Matcher<T>, getter: (Configuration) -> T) {
355                 val configuration = Configuration(MapConfigurationBackend())
356                 preferences.saveTo(configuration)
357                 assertThat(getter(configuration), matcher)
358         }
359
360         private fun <T : Any> testPreferencesChangedEvent(name: String, setter: (T) -> Unit, value: T) {
361                 val events = mutableListOf<PreferenceChangedEvent>()
362                 eventBus.register(object {
363                         @Subscribe
364                         fun preferenceChanged(event: PreferenceChangedEvent) =
365                                         events.add(event)
366                 })
367                 setter(value)
368                 assertThat(events, hasItem(PreferenceChangedEvent(name, value)))
369         }
370
371 }