🚧 Add option for “strict filtering”
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / core / PreferencesTest.kt
index f4f4818..dafe782 100644 (file)
@@ -1,60 +1,79 @@
 package net.pterodactylus.sone.core
 
-import com.google.common.eventbus.*
-import net.pterodactylus.sone.core.event.*
-import net.pterodactylus.sone.fcp.FcpInterface.*
-import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.*
-import net.pterodactylus.sone.fcp.event.*
-import net.pterodactylus.sone.test.*
-import org.hamcrest.MatcherAssert.*
-import org.hamcrest.Matchers.*
-import org.junit.*
-import org.mockito.ArgumentMatchers.any
-import org.mockito.Mockito.atLeastOnce
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
+import com.google.common.eventbus.EventBus
+import com.google.common.eventbus.Subscribe
+import net.pterodactylus.sone.core.event.InsertionDelayChangedEvent
+import net.pterodactylus.sone.core.event.StrictFilteringActivatedEvent
+import net.pterodactylus.sone.core.event.StrictFilteringDeactivatedEvent
+import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired
+import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.ALWAYS
+import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.NO
+import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.WRITING
+import net.pterodactylus.sone.fcp.event.FcpInterfaceActivatedEvent
+import net.pterodactylus.sone.fcp.event.FcpInterfaceDeactivatedEvent
+import net.pterodactylus.sone.fcp.event.FullAccessRequiredChanged
+import net.pterodactylus.util.config.Configuration
+import net.pterodactylus.util.config.MapConfigurationBackend
+import org.hamcrest.Matcher
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.emptyIterable
+import org.hamcrest.Matchers.equalTo
+import org.hamcrest.Matchers.hasItem
+import org.hamcrest.Matchers.instanceOf
+import org.hamcrest.Matchers.nullValue
+import org.junit.Test
 
 /**
  * Unit test for [Preferences].
  */
 class PreferencesTest {
 
-       private val eventBus = mock<EventBus>()
+       private val eventBus = EventBus()
        private val preferences = Preferences(eventBus)
-       private val eventsCaptor = capture<Any>()
 
        @Test
        fun `preferences retain insertion delay`() {
-               preferences.insertionDelay = 15
+               preferences.newInsertionDelay = 15
                assertThat(preferences.insertionDelay, equalTo(15))
        }
 
        @Test
        fun `preferences sends event on setting insertion delay`() {
-               preferences.insertionDelay = 15
-               verify(eventBus, atLeastOnce()).post(eventsCaptor.capture())
-               assertThat(eventsCaptor.allValues, hasItem(InsertionDelayChangedEvent(15)))
+               val events = mutableListOf<InsertionDelayChangedEvent>()
+               eventBus.register(object {
+                       @Subscribe
+                       fun insertionDelayChangedEvent(event: InsertionDelayChangedEvent) =
+                                       events.add(event)
+               })
+               preferences.newInsertionDelay = 15
+               assertThat(events, hasItem(InsertionDelayChangedEvent(15)))
        }
 
        @Test(expected = IllegalArgumentException::class)
        fun `invalid insertion delay is rejected`() {
-               preferences.insertionDelay = -15
+               preferences.newInsertionDelay = -15
        }
 
        @Test
        fun `no event is sent when invalid insertion delay is set`() {
+               val events = mutableListOf<InsertionDelayChangedEvent>()
+               eventBus.register(object {
+                       @Subscribe
+                       fun insertionDelayChanged(event: InsertionDelayChangedEvent) =
+                                       events.add(event)
+               })
                try {
-                       preferences.insertionDelay = -15
+                       preferences.newInsertionDelay = -15
                } catch (iae: IllegalArgumentException) {
                        /* ignore. */
                }
 
-               verify(eventBus, never()).post(any())
+               assertThat(events, emptyIterable())
        }
 
        @Test
        fun `preferences return default value when insertion delay is set to null`() {
-               preferences.setInsertionDelay(null)
+               preferences.newInsertionDelay = null
                assertThat(preferences.insertionDelay, equalTo(60))
        }
 
@@ -64,19 +83,24 @@ class PreferencesTest {
        }
 
        @Test
+       fun `preferences saves null for default insertion delay setting`() {
+               verifySavedOption(nullValue()) { it.getIntValue("Option/InsertionDelay").getValue(null) }
+       }
+
+       @Test
        fun `preferences retain posts per page`() {
-               preferences.postsPerPage = 15
+               preferences.newPostsPerPage = 15
                assertThat(preferences.postsPerPage, equalTo(15))
        }
 
        @Test(expected = IllegalArgumentException::class)
        fun `invalid posts per page is rejected`() {
-               preferences.postsPerPage = -15
+               preferences.newPostsPerPage = -15
        }
 
        @Test
        fun `preferences return default value when posts per page is set to null`() {
-               preferences.setPostsPerPage(null)
+               preferences.newPostsPerPage = null
                assertThat(preferences.postsPerPage, equalTo(10))
        }
 
@@ -87,18 +111,18 @@ class PreferencesTest {
 
        @Test
        fun `preferences retain images per page`() {
-               preferences.imagesPerPage = 15
+               preferences.newImagesPerPage = 15
                assertThat(preferences.imagesPerPage, equalTo(15))
        }
 
        @Test(expected = IllegalArgumentException::class)
        fun `invalid images per page is rejected`() {
-               preferences.imagesPerPage = -15
+               preferences.newImagesPerPage = -15
        }
 
        @Test
        fun `preferences return default value when images per page is set to null`() {
-               preferences.setImagesPerPage(null)
+               preferences.newImagesPerPage = null
                assertThat(preferences.imagesPerPage, equalTo(9))
        }
 
@@ -109,18 +133,18 @@ class PreferencesTest {
 
        @Test
        fun `preferences retain characters per post`() {
-               preferences.charactersPerPost = 150
+               preferences.newCharactersPerPost = 150
                assertThat(preferences.charactersPerPost, equalTo(150))
        }
 
        @Test(expected = IllegalArgumentException::class)
        fun `invalid characters per post is rejected`() {
-               preferences.charactersPerPost = -15
+               preferences.newCharactersPerPost = -15
        }
 
        @Test
        fun `preferences return default value when characters per post is set to null`() {
-               preferences.setCharactersPerPost(null)
+               preferences.newCharactersPerPost = null
                assertThat(preferences.charactersPerPost, equalTo(400))
        }
 
@@ -131,23 +155,23 @@ class PreferencesTest {
 
        @Test
        fun `preferences retain post cut off length`() {
-               preferences.postCutOffLength = 150
+               preferences.newPostCutOffLength = 150
                assertThat(preferences.postCutOffLength, equalTo(150))
        }
 
        @Test(expected = IllegalArgumentException::class)
        fun `invalid post cut off length is rejected`() {
-               preferences.postCutOffLength = -15
+               preferences.newPostCutOffLength = -15
        }
 
        @Test(expected = IllegalArgumentException::class)
        fun `cut off length of minus one is not allowed`() {
-               preferences.postCutOffLength = -1
+               preferences.newPostCutOffLength = -1
        }
 
        @Test
        fun `preferences return default value when post cut off length is set to null`() {
-               preferences.setPostCutOffLength(null)
+               preferences.newPostCutOffLength = null
                assertThat(preferences.postCutOffLength, equalTo(200))
        }
 
@@ -158,169 +182,190 @@ class PreferencesTest {
 
        @Test
        fun `preferences retain require full access of true`() {
-               preferences.isRequireFullAccess = true
-               assertThat(preferences.isRequireFullAccess, equalTo(true))
+               preferences.newRequireFullAccess = true
+               assertThat(preferences.requireFullAccess, equalTo(true))
        }
 
        @Test
        fun `preferences retain require full access of false`() {
-               preferences.isRequireFullAccess = false
-               assertThat(preferences.isRequireFullAccess, equalTo(false))
+               preferences.newRequireFullAccess = false
+               assertThat(preferences.requireFullAccess, equalTo(false))
        }
 
        @Test
        fun `preferences return default value when require full access is set to null`() {
-               preferences.setRequireFullAccess(null)
-               assertThat(preferences.isRequireFullAccess, equalTo(false))
+               preferences.newRequireFullAccess = null
+               assertThat(preferences.requireFullAccess, equalTo(false))
        }
 
        @Test
        fun `preferences start with require full access default value`() {
-               assertThat(preferences.isRequireFullAccess, equalTo(false))
+               assertThat(preferences.requireFullAccess, equalTo(false))
        }
 
        @Test
-       fun `preferences retain positive trust`() {
-               preferences.positiveTrust = 15
-               assertThat(preferences.positiveTrust, equalTo(15))
+       fun `preferences retain fcp interface active of true`() {
+               val events = mutableListOf<FcpInterfaceActivatedEvent>()
+               eventBus.register(object {
+                       @Subscribe
+                       fun fcpInterfaceActivatedEvent(event: FcpInterfaceActivatedEvent) =
+                                       events.add(event)
+               })
+               preferences.newFcpInterfaceActive = true
+               assertThat(preferences.fcpInterfaceActive, equalTo(true))
+               assertThat(events, hasItem<FcpInterfaceActivatedEvent>(instanceOf(FcpInterfaceActivatedEvent::class.java)))
        }
 
-       @Test(expected = IllegalArgumentException::class)
-       fun `invalid positive trust is rejected`() {
-               preferences.positiveTrust = -15
+       @Test
+       fun `preferences retain fcp interface active of false`() {
+               val events = mutableListOf<FcpInterfaceDeactivatedEvent>()
+               eventBus.register(object {
+                       @Subscribe
+                       fun fcpInterfaceDeactivatedEvent(event: FcpInterfaceDeactivatedEvent) =
+                                       events.add(event)
+               })
+               preferences.newFcpInterfaceActive = false
+               assertThat(preferences.fcpInterfaceActive, equalTo(false))
+               assertThat(events, hasItem<FcpInterfaceDeactivatedEvent>(instanceOf(FcpInterfaceDeactivatedEvent::class.java)))
        }
 
        @Test
-       fun `preferences return default value when positive trust is set to null`() {
-               preferences.setPositiveTrust(null)
-               assertThat(preferences.positiveTrust, equalTo(75))
+       fun `preferences return default value when fcp interface active is set to null`() {
+               val events = mutableListOf<FcpInterfaceDeactivatedEvent>()
+               eventBus.register(object {
+                       @Subscribe
+                       fun fcpInterfaceDeactivatedEvent(event: FcpInterfaceDeactivatedEvent) =
+                                       events.add(event)
+               })
+               preferences.newFcpInterfaceActive = null
+               assertThat(preferences.fcpInterfaceActive, equalTo(false))
+               assertThat(events, hasItem<FcpInterfaceDeactivatedEvent>(instanceOf(FcpInterfaceDeactivatedEvent::class.java)))
        }
 
        @Test
-       fun `preferences start with positive trust default value`() {
-               assertThat(preferences.positiveTrust, equalTo(75))
+       fun `preferences start with fcp interface active default value`() {
+               assertThat(preferences.fcpInterfaceActive, equalTo(false))
        }
 
        @Test
-       fun `preferences retain negative trust`() {
-               preferences.negativeTrust = -15
-               assertThat(preferences.negativeTrust, equalTo(-15))
+       fun `preferences retain fcp full access required of no`() {
+               verifyFullAccessRequiredChangedEvent(NO)
        }
 
-       @Test(expected = IllegalArgumentException::class)
-       fun `invalid negative trust is rejected`() {
-               preferences.negativeTrust = 150
+       private fun verifyFullAccessRequiredChangedEvent(set: FullAccessRequired?, expected: FullAccessRequired = set!!) {
+               val events = mutableListOf<FullAccessRequiredChanged>()
+               eventBus.register(object {
+                       @Subscribe
+                       fun fullAccessRequiredChanged(event: FullAccessRequiredChanged) =
+                                       events.add(event)
+               })
+               preferences.newFcpFullAccessRequired = set
+               assertThat(preferences.fcpFullAccessRequired, equalTo(expected))
+               assertThat(events.single().fullAccessRequired, equalTo(expected))
        }
 
        @Test
-       fun `preferences return default value when negative trust is set to null`() {
-               preferences.setNegativeTrust(null)
-               assertThat(preferences.negativeTrust, equalTo(-25))
+       fun `preferences retain fcp full access required of writing`() {
+               verifyFullAccessRequiredChangedEvent(WRITING)
        }
 
        @Test
-       fun `preferences start with negative trust default value`() {
-               assertThat(preferences.negativeTrust, equalTo(-25))
+       fun `preferences retain fcp full access required of always`() {
+               verifyFullAccessRequiredChangedEvent(ALWAYS)
        }
 
        @Test
-       fun `preferences retain trust comment`() {
-               preferences.trustComment = "Trust"
-               assertThat(preferences.trustComment, equalTo("Trust"))
+       fun `preferences return default value when fcp full access required is set to null`() {
+               verifyFullAccessRequiredChangedEvent(null, ALWAYS)
        }
 
        @Test
-       fun `preferences return default value when trust comment is set to null`() {
-               preferences.trustComment = null
-               assertThat(preferences.trustComment,
-                               equalTo("Set from Sone Web Interface"))
+       fun `preferences start with fcp full access required default value`() {
+               assertThat(preferences.fcpFullAccessRequired, equalTo(ALWAYS))
        }
 
        @Test
-       fun `preferences start with trust comment default value`() {
-               assertThat(preferences.trustComment,
-                               equalTo("Set from Sone Web Interface"))
+       fun `setting insertion delay to valid value sends change event`() {
+               testPreferencesChangedEvent("InsertionDelay", { preferences.newInsertionDelay = it }, 30)
        }
 
        @Test
-       fun `preferences retain fcp interface active of true`() {
-               preferences.isFcpInterfaceActive = true
-               assertThat(preferences.isFcpInterfaceActive, equalTo(true))
-               verify(eventBus).post(any(FcpInterfaceActivatedEvent::class.java))
+       fun `setting posts per page to valid value sends change event`() {
+               testPreferencesChangedEvent("PostsPerPage", { preferences.newPostsPerPage = it }, 31)
        }
 
        @Test
-       fun `preferences retain fcp interface active of false`() {
-               preferences.isFcpInterfaceActive = false
-               assertThat(preferences.isFcpInterfaceActive, equalTo(false))
-               verify(eventBus).post(any(FcpInterfaceDeactivatedEvent::class.java))
+       fun `default strict filtering is false`() {
+               assertThat(preferences.strictFiltering, equalTo(false))
        }
 
        @Test
-       fun `preferences return default value when fcp interface active is set to null`() {
-               preferences.setFcpInterfaceActive(null)
-               assertThat(preferences.isFcpInterfaceActive, equalTo(false))
-               verify(eventBus).post(any(FcpInterfaceDeactivatedEvent::class.java))
+       fun `strict filtering can be set`() {
+               preferences.newStrictFiltering = true
+               assertThat(preferences.strictFiltering, equalTo(true))
        }
 
        @Test
-       fun `preferences start with fcp interface active default value`() {
-               assertThat(preferences.isFcpInterfaceActive, equalTo(false))
+       fun `strict filtering returns to default on null`() {
+               preferences.newStrictFiltering = true
+               preferences.newStrictFiltering = null
+               assertThat(preferences.strictFiltering, equalTo(false))
        }
 
        @Test
-       fun `preferences retain fcp full access required of no`() {
-               preferences.fcpFullAccessRequired = NO
-               assertThat(preferences.fcpFullAccessRequired, equalTo(NO))
-               verifyFullAccessRequiredChangedEvent(NO)
-       }
-
-       private fun verifyFullAccessRequiredChangedEvent(
-                       fullAccessRequired: FullAccessRequired) {
-               verify(eventBus).post(eventsCaptor.capture())
-               assertThat(eventsCaptor.value, instanceOf(FullAccessRequiredChanged::class.java))
-               assertThat((eventsCaptor.value as FullAccessRequiredChanged).fullAccessRequired,
-                               equalTo(fullAccessRequired))
+       fun `event is generated when strict filtering is activated`() {
+               val events = mutableListOf<StrictFilteringActivatedEvent>()
+               eventBus.register(object {
+                       @Subscribe fun strictFilteringActivatedEvent(event: StrictFilteringActivatedEvent) =
+                                       events.add(event)
+               })
+               preferences.newStrictFiltering = true
+               assertThat(events, hasItem<StrictFilteringActivatedEvent>(instanceOf(StrictFilteringActivatedEvent::class.java)))
        }
 
        @Test
-       fun `preferences retain fcp full access required of writing`() {
-               preferences.fcpFullAccessRequired = WRITING
-               assertThat(preferences.fcpFullAccessRequired, equalTo(WRITING))
-               verifyFullAccessRequiredChangedEvent(WRITING)
+       fun `event is generated when strict filtering is deactivated`() {
+               val events = mutableListOf<StrictFilteringDeactivatedEvent>()
+               eventBus.register(object {
+                       @Subscribe fun strictFilteringDeactivatedEvent(event: StrictFilteringDeactivatedEvent) =
+                                       events.add(event)
+               })
+               preferences.newStrictFiltering = false
+               assertThat(events, hasItem<StrictFilteringDeactivatedEvent>(instanceOf(StrictFilteringDeactivatedEvent::class.java)))
        }
 
        @Test
-       fun `preferences retain fcp full access required of always`() {
-               preferences.fcpFullAccessRequired = ALWAYS
-               assertThat(preferences.fcpFullAccessRequired, equalTo(ALWAYS))
-               verifyFullAccessRequiredChangedEvent(ALWAYS)
+       fun `default strict filtering is saved as null`() {
+               verifySavedOption(nullValue()) { it.getBooleanValue("Option/StrictFiltering").value }
        }
 
        @Test
-       fun `preferences return default value when fcp full access required is set to null`() {
-               preferences.fcpFullAccessRequired = null
-               assertThat(preferences.fcpFullAccessRequired, equalTo(ALWAYS))
-               verifyFullAccessRequiredChangedEvent(ALWAYS)
+       fun `activated strict filtering is saved as true`() {
+               preferences.newStrictFiltering = true
+               verifySavedOption(equalTo(true)) { it.getBooleanValue("Option/StrictFiltering").value }
        }
 
        @Test
-       fun `preferences start with fcp full access required default value`() {
-               assertThat(preferences.fcpFullAccessRequired, equalTo(ALWAYS))
+       fun `deactivated strict filtering is saved as false`() {
+               preferences.newStrictFiltering = false
+               verifySavedOption(equalTo(false)) { it.getBooleanValue("Option/StrictFiltering").value }
        }
 
-       @Test
-       fun `setting insertion delay to valid value sends change event`() {
-               preferences.insertionDelay = 30
-               verify(eventBus, atLeastOnce()).post(eventsCaptor.capture())
-               assertThat(eventsCaptor.allValues, hasItem(PreferenceChangedEvent("InsertionDelay", 30)))
+       private fun <T> verifySavedOption(matcher: Matcher<T>, getter: (Configuration) -> T) {
+               val configuration = Configuration(MapConfigurationBackend())
+               preferences.saveTo(configuration)
+               assertThat(getter(configuration), matcher)
        }
 
-       @Test
-       fun `setting posts per page to valid value sends change event`() {
-               preferences.postsPerPage = 30
-               verify(eventBus, atLeastOnce()).post(eventsCaptor.capture())
-               assertThat(eventsCaptor.allValues, hasItem(PreferenceChangedEvent("PostsPerPage", 30)))
+       private fun <T : Any> testPreferencesChangedEvent(name: String, setter: (T) -> Unit, value: T) {
+               val events = mutableListOf<PreferenceChangedEvent>()
+               eventBus.register(object {
+                       @Subscribe
+                       fun preferenceChanged(event: PreferenceChangedEvent) =
+                                       events.add(event)
+               })
+               setter(value)
+               assertThat(events, hasItem(PreferenceChangedEvent(name, value)))
        }
 
 }