1 package net.pterodactylus.sone.core
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
27 * Unit test for [Preferences].
29 class PreferencesTest {
31 private val eventBus = EventBus()
32 private val preferences = Preferences(eventBus)
35 fun `preferences retain insertion delay`() {
36 preferences.newInsertionDelay = 15
37 assertThat(preferences.insertionDelay, equalTo(15))
41 fun `preferences sends event on setting insertion delay`() {
42 val events = mutableListOf<InsertionDelayChangedEvent>()
43 eventBus.register(object {
45 fun insertionDelayChangedEvent(event: InsertionDelayChangedEvent) =
48 preferences.newInsertionDelay = 15
49 assertThat(events, hasItem(InsertionDelayChangedEvent(15)))
52 @Test(expected = IllegalArgumentException::class)
53 fun `invalid insertion delay is rejected`() {
54 preferences.newInsertionDelay = -15
58 fun `no event is sent when invalid insertion delay is set`() {
59 val events = mutableListOf<InsertionDelayChangedEvent>()
60 eventBus.register(object {
62 fun insertionDelayChanged(event: InsertionDelayChangedEvent) =
66 preferences.newInsertionDelay = -15
67 } catch (iae: IllegalArgumentException) {
71 assertThat(events, emptyIterable())
75 fun `preferences return default value when insertion delay is set to null`() {
76 preferences.newInsertionDelay = null
77 assertThat(preferences.insertionDelay, equalTo(60))
81 fun `preferences start with insertion delay default value`() {
82 assertThat(preferences.insertionDelay, equalTo(60))
86 fun `preferences saves null for default insertion delay setting`() {
87 verifySavedOption(nullValue()) { it.getIntValue("Option/InsertionDelay").getValue(null) }
91 fun `preferences retain posts per page`() {
92 preferences.newPostsPerPage = 15
93 assertThat(preferences.postsPerPage, equalTo(15))
96 @Test(expected = IllegalArgumentException::class)
97 fun `invalid posts per page is rejected`() {
98 preferences.newPostsPerPage = -15
102 fun `preferences return default value when posts per page is set to null`() {
103 preferences.newPostsPerPage = null
104 assertThat(preferences.postsPerPage, equalTo(10))
108 fun `preferences start with posts per page default value`() {
109 assertThat(preferences.postsPerPage, equalTo(10))
113 fun `preferences retain images per page`() {
114 preferences.newImagesPerPage = 15
115 assertThat(preferences.imagesPerPage, equalTo(15))
118 @Test(expected = IllegalArgumentException::class)
119 fun `invalid images per page is rejected`() {
120 preferences.newImagesPerPage = -15
124 fun `preferences return default value when images per page is set to null`() {
125 preferences.newImagesPerPage = null
126 assertThat(preferences.imagesPerPage, equalTo(9))
130 fun `preferences start with images per page default value`() {
131 assertThat(preferences.imagesPerPage, equalTo(9))
135 fun `preferences retain characters per post`() {
136 preferences.newCharactersPerPost = 150
137 assertThat(preferences.charactersPerPost, equalTo(150))
140 @Test(expected = IllegalArgumentException::class)
141 fun `invalid characters per post is rejected`() {
142 preferences.newCharactersPerPost = -15
146 fun `preferences return default value when characters per post is set to null`() {
147 preferences.newCharactersPerPost = null
148 assertThat(preferences.charactersPerPost, equalTo(400))
152 fun `preferences start with characters per post default value`() {
153 assertThat(preferences.charactersPerPost, equalTo(400))
157 fun `preferences retain post cut off length`() {
158 preferences.newPostCutOffLength = 150
159 assertThat(preferences.postCutOffLength, equalTo(150))
162 @Test(expected = IllegalArgumentException::class)
163 fun `invalid post cut off length is rejected`() {
164 preferences.newPostCutOffLength = -15
167 @Test(expected = IllegalArgumentException::class)
168 fun `cut off length of minus one is not allowed`() {
169 preferences.newPostCutOffLength = -1
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))
179 fun `preferences start with post cut off length default value`() {
180 assertThat(preferences.postCutOffLength, equalTo(200))
184 fun `preferences retain require full access of true`() {
185 preferences.newRequireFullAccess = true
186 assertThat(preferences.requireFullAccess, equalTo(true))
190 fun `preferences retain require full access of false`() {
191 preferences.newRequireFullAccess = false
192 assertThat(preferences.requireFullAccess, equalTo(false))
196 fun `preferences return default value when require full access is set to null`() {
197 preferences.newRequireFullAccess = null
198 assertThat(preferences.requireFullAccess, equalTo(false))
202 fun `preferences start with require full access default value`() {
203 assertThat(preferences.requireFullAccess, equalTo(false))
207 fun `preferences retain fcp interface active of true`() {
208 val events = mutableListOf<FcpInterfaceActivatedEvent>()
209 eventBus.register(object {
211 fun fcpInterfaceActivatedEvent(event: FcpInterfaceActivatedEvent) =
214 preferences.newFcpInterfaceActive = true
215 assertThat(preferences.fcpInterfaceActive, equalTo(true))
216 assertThat(events, hasItem<FcpInterfaceActivatedEvent>(instanceOf(FcpInterfaceActivatedEvent::class.java)))
220 fun `preferences retain fcp interface active of false`() {
221 val events = mutableListOf<FcpInterfaceDeactivatedEvent>()
222 eventBus.register(object {
224 fun fcpInterfaceDeactivatedEvent(event: FcpInterfaceDeactivatedEvent) =
227 preferences.newFcpInterfaceActive = false
228 assertThat(preferences.fcpInterfaceActive, equalTo(false))
229 assertThat(events, hasItem<FcpInterfaceDeactivatedEvent>(instanceOf(FcpInterfaceDeactivatedEvent::class.java)))
233 fun `preferences return default value when fcp interface active is set to null`() {
234 val events = mutableListOf<FcpInterfaceDeactivatedEvent>()
235 eventBus.register(object {
237 fun fcpInterfaceDeactivatedEvent(event: FcpInterfaceDeactivatedEvent) =
240 preferences.newFcpInterfaceActive = null
241 assertThat(preferences.fcpInterfaceActive, equalTo(false))
242 assertThat(events, hasItem<FcpInterfaceDeactivatedEvent>(instanceOf(FcpInterfaceDeactivatedEvent::class.java)))
246 fun `preferences start with fcp interface active default value`() {
247 assertThat(preferences.fcpInterfaceActive, equalTo(false))
251 fun `preferences retain fcp full access required of no`() {
252 verifyFullAccessRequiredChangedEvent(NO)
255 private fun verifyFullAccessRequiredChangedEvent(set: FullAccessRequired?, expected: FullAccessRequired = set!!) {
256 val events = mutableListOf<FullAccessRequiredChanged>()
257 eventBus.register(object {
259 fun fullAccessRequiredChanged(event: FullAccessRequiredChanged) =
262 preferences.newFcpFullAccessRequired = set
263 assertThat(preferences.fcpFullAccessRequired, equalTo(expected))
264 assertThat(events.single().fullAccessRequired, equalTo(expected))
268 fun `preferences retain fcp full access required of writing`() {
269 verifyFullAccessRequiredChangedEvent(WRITING)
273 fun `preferences retain fcp full access required of always`() {
274 verifyFullAccessRequiredChangedEvent(ALWAYS)
278 fun `preferences return default value when fcp full access required is set to null`() {
279 verifyFullAccessRequiredChangedEvent(null, ALWAYS)
283 fun `preferences start with fcp full access required default value`() {
284 assertThat(preferences.fcpFullAccessRequired, equalTo(ALWAYS))
288 fun `setting insertion delay to valid value sends change event`() {
289 testPreferencesChangedEvent("InsertionDelay", { preferences.newInsertionDelay = it }, 30)
293 fun `setting posts per page to valid value sends change event`() {
294 testPreferencesChangedEvent("PostsPerPage", { preferences.newPostsPerPage = it }, 31)
298 fun `default strict filtering is false`() {
299 assertThat(preferences.strictFiltering, equalTo(false))
303 fun `strict filtering can be set`() {
304 preferences.newStrictFiltering = true
305 assertThat(preferences.strictFiltering, equalTo(true))
309 fun `strict filtering returns to default on null`() {
310 preferences.newStrictFiltering = true
311 preferences.newStrictFiltering = null
312 assertThat(preferences.strictFiltering, equalTo(false))
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) =
322 preferences.newStrictFiltering = true
323 assertThat(events, hasItem<StrictFilteringActivatedEvent>(instanceOf(StrictFilteringActivatedEvent::class.java)))
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) =
333 preferences.newStrictFiltering = false
334 assertThat(events, hasItem<StrictFilteringDeactivatedEvent>(instanceOf(StrictFilteringDeactivatedEvent::class.java)))
338 fun `default strict filtering is saved as null`() {
339 verifySavedOption(nullValue()) { it.getBooleanValue("Option/StrictFiltering").value }
343 fun `activated strict filtering is saved as true`() {
344 preferences.newStrictFiltering = true
345 verifySavedOption(equalTo(true)) { it.getBooleanValue("Option/StrictFiltering").value }
349 fun `deactivated strict filtering is saved as false`() {
350 preferences.newStrictFiltering = false
351 verifySavedOption(equalTo(false)) { it.getBooleanValue("Option/StrictFiltering").value }
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)
360 private fun <T : Any> testPreferencesChangedEvent(name: String, setter: (T) -> Unit, value: T) {
361 val events = mutableListOf<PreferenceChangedEvent>()
362 eventBus.register(object {
364 fun preferenceChanged(event: PreferenceChangedEvent) =
368 assertThat(events, hasItem(PreferenceChangedEvent(name, value)))