✨ Add preferences for max age of post to load
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Mon, 20 Jul 2026 15:18:25 +0000 (17:18 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 22 Jul 2026 16:38:45 +0000 (18:38 +0200)
src/main/kotlin/net/pterodactylus/sone/core/Preferences.kt
src/main/kotlin/net/pterodactylus/sone/core/PreferencesLoader.kt
src/main/kotlin/net/pterodactylus/sone/core/event/MaxAgeOfPostsToLoadChangedEvent.kt [new file with mode: 0644]
src/test/kotlin/net/pterodactylus/sone/core/PreferencesLoaderTest.kt
src/test/kotlin/net/pterodactylus/sone/core/PreferencesTest.kt

index 314d66a..cb614ea 100644 (file)
@@ -30,6 +30,7 @@ import net.pterodactylus.sone.utils.DefaultOption
 import net.pterodactylus.util.config.Configuration
 import net.pterodactylus.util.config.ConfigurationException
 import java.lang.Integer.MAX_VALUE
+import net.pterodactylus.sone.core.event.MaxAgeOfPostsToLoadChangedEvent
 
 /**
  * Convenience interface for external classes that want to access the core’s
@@ -110,6 +111,18 @@ class DefaultPreferences(private val eventBus: EventBus) {
                        }
                }
 
+       private val _maxAgeOfPostsToLoad = DefaultOption(365)
+       val maxAgeOfPostsToLoad: Int get() = _maxAgeOfPostsToLoad.get()
+       var newMaxAgeOfPostsToLoad: Int?
+               get() = unsupported
+               set(value) {
+                       if ((value ?: 0) < 0) {
+                               throw IllegalArgumentException("maxAgeOfPostsToLoad cannot be negative")
+                       }
+                       _maxAgeOfPostsToLoad.set(value)
+                       eventBus.post(MaxAgeOfPostsToLoadChangedEvent(_maxAgeOfPostsToLoad.get()))
+               }
+
        @Throws(ConfigurationException::class)
        fun saveTo(configuration: Configuration) {
                configuration.getIntValue("Option/ConfigurationVersion").value = 0
@@ -122,6 +135,7 @@ class DefaultPreferences(private val eventBus: EventBus) {
                configuration.getBooleanValue("Option/ActivateFcpInterface").value = _fcpInterfaceActive.real
                configuration.getIntValue("Option/FcpFullAccessRequired").value = toInt(_fcpFullAccessRequired.real)
                configuration.getBooleanValue("Option/StrictFiltering").value = _strictFiltering.real
+               configuration.getIntValue("Option/MaxAgeOfPostsToLoad").value = _maxAgeOfPostsToLoad.real
        }
 
        private fun toInt(fullAccessRequired: FullAccessRequired?): Int? {
index 5e8b7e8..2eaae0e 100644 (file)
@@ -18,6 +18,7 @@ class PreferencesLoader(private val preferences: DefaultPreferences) {
                loadFcpInterfaceActive(configuration)
                loadFcpFullAccessRequired(configuration)
                loadStrictFiltering(configuration)
+               loadMaxAgeOfPostsToLoad(configuration)
        }
 
        private fun loadInsertionDelay(configuration: Configuration) {
@@ -60,4 +61,8 @@ class PreferencesLoader(private val preferences: DefaultPreferences) {
                preferences.newStrictFiltering = configuration.getBooleanValue("Option/StrictFiltering").getValue(null)
        }
 
+       private fun loadMaxAgeOfPostsToLoad(configuration: Configuration) {
+               preferences.newMaxAgeOfPostsToLoad = configuration.getIntValue("Option/MaxAgeOfPostsToLoad").getValue(null)
+       }
+
 }
diff --git a/src/main/kotlin/net/pterodactylus/sone/core/event/MaxAgeOfPostsToLoadChangedEvent.kt b/src/main/kotlin/net/pterodactylus/sone/core/event/MaxAgeOfPostsToLoadChangedEvent.kt
new file mode 100644 (file)
index 0000000..622ff30
--- /dev/null
@@ -0,0 +1,3 @@
+package net.pterodactylus.sone.core.event
+
+data class MaxAgeOfPostsToLoadChangedEvent(val newMaxAgeOfPostsToLoad: Int)
index a90d87c..3909cbf 100644 (file)
@@ -29,12 +29,17 @@ class PreferencesLoaderTest {
                setupBooleanValue("ActivateFcpInterface", true)
                setupIntValue("FcpFullAccessRequired", 1)
                setupBooleanValue("StrictFiltering", true)
+               setupLongValue("MaxAgeOfPostsToLoad", 123)
        }
 
        private fun setupIntValue(optionName: String, value: Int) {
                configuration.getIntValue("Option/$optionName").value = value
        }
 
+       private fun setupLongValue(optionName: String, value: Long) {
+               configuration.getLongValue("Option/$optionName").value = value
+       }
+
        private fun setupBooleanValue(optionName: String, value: Boolean) {
                configuration.getBooleanValue("Option/$optionName").value = value
        }
@@ -51,6 +56,13 @@ class PreferencesLoaderTest {
                assertThat(preferences.fcpInterfaceActive, equalTo(true))
                assertThat(preferences.fcpFullAccessRequired, equalTo(FullAccessRequired.WRITING))
                assertThat(preferences.strictFiltering, equalTo(true))
+               assertThat(preferences.maxAgeOfPostsToLoad, equalTo(123))
+       }
+
+       @Test
+       fun `configuration without max age of posts to load can be loaded correctly`() {
+               configuration.getLongValue("Option/MaxAgeOfPostsToLoad").value = null
+               preferencesLoader.loadFrom(configuration)
        }
 
        @Test
index 37a845a..a540f6e 100644 (file)
@@ -3,6 +3,7 @@ package net.pterodactylus.sone.core
 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.MaxAgeOfPostsToLoadChangedEvent
 import net.pterodactylus.sone.core.event.StrictFilteringActivatedEvent
 import net.pterodactylus.sone.core.event.StrictFilteringDeactivatedEvent
 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired
@@ -12,10 +13,12 @@ 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.sone.test.assertThrows
 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
 import org.hamcrest.Matchers.emptyIterable
 import org.hamcrest.Matchers.equalTo
 import org.hamcrest.Matchers.hasItem
@@ -341,6 +344,56 @@ class DefaultPreferencesTest {
                verifySavedOption(equalTo(false)) { it.getBooleanValue("Option/StrictFiltering").value }
        }
 
+       @Test
+       fun `default max age of posts to load is 365 days`() {
+               assertThat(preferences.maxAgeOfPostsToLoad, equalTo(365))
+       }
+
+       @Test
+       fun `max age of posts to load value is retained`() {
+               preferences.newMaxAgeOfPostsToLoad = 30
+               assertThat(preferences.maxAgeOfPostsToLoad, equalTo(30))
+       }
+
+       @Test
+       fun `max age of posts cannot be set to negative duration`() {
+               assertThrows<IllegalArgumentException> { preferences.newMaxAgeOfPostsToLoad = -1 }
+       }
+
+       @Test
+       fun `setting max age of posts to load sends event`() {
+               val events = mutableListOf<MaxAgeOfPostsToLoadChangedEvent>()
+               eventBus.register(object {
+                       @Subscribe fun maxAgeOfPostsToLoadChangedEvent(event: MaxAgeOfPostsToLoadChangedEvent) =
+                               events.add(event)
+               })
+               preferences.newMaxAgeOfPostsToLoad = 30
+               assertThat(events, Matchers.contains(MaxAgeOfPostsToLoadChangedEvent(30)))
+       }
+
+       @Test
+       fun `setting max age of posts to load to null restores default value`() {
+               preferences.newMaxAgeOfPostsToLoad = 30
+               preferences.newMaxAgeOfPostsToLoad = null
+               assertThat(preferences.maxAgeOfPostsToLoad, equalTo(365))
+       }
+
+       @Test
+       fun `getting value from max age of posts to load setter is unsupported`() {
+               assertThrows<UnsupportedOperationException> { preferences.newMaxAgeOfPostsToLoad }
+       }
+
+       @Test
+       fun `default max age of posts to load is stored as null`() {
+               verifySavedOption(nullValue()) { it.getIntValue("Option/MaxAgeOfPostsToLoad").getValue(null) }
+       }
+
+       @Test
+       fun `custom max age of posts to load is stored as millis`() {
+               preferences.newMaxAgeOfPostsToLoad = 30
+               verifySavedOption(equalTo(30)) { it.getIntValue("Option/MaxAgeOfPostsToLoad").value }
+       }
+
        private fun <T> verifySavedOption(matcher: Matcher<T>, getter: (Configuration) -> T) {
                val configuration = Configuration(MapConfigurationBackend())
                preferences.saveTo(configuration)