♻️ Extract interface for list notification filter
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 1 Jul 2020 16:56:14 +0000 (18:56 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 1 Jul 2020 20:15:27 +0000 (22:15 +0200)
src/main/kotlin/net/pterodactylus/sone/notify/DefaultListNotificationFilter.kt [new file with mode: 0644]
src/main/kotlin/net/pterodactylus/sone/notify/ListNotificationFilter.kt
src/test/kotlin/net/pterodactylus/sone/notify/ListNotificationFilterTest.kt

diff --git a/src/main/kotlin/net/pterodactylus/sone/notify/DefaultListNotificationFilter.kt b/src/main/kotlin/net/pterodactylus/sone/notify/DefaultListNotificationFilter.kt
new file mode 100644 (file)
index 0000000..acd2bce
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Sone - DefaultListNotificationFilter.kt - Copyright © 2010–2020 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package net.pterodactylus.sone.notify
+
+import net.pterodactylus.sone.data.Post
+import net.pterodactylus.sone.data.PostReply
+import net.pterodactylus.sone.data.Sone
+import net.pterodactylus.sone.utils.ifTrue
+import net.pterodactylus.util.notify.Notification
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * Filter for [ListNotification]s.
+ */
+@Singleton
+class DefaultListNotificationFilter @Inject constructor(private val postVisibilityFilter: PostVisibilityFilter, private val replyVisibilityFilter: ReplyVisibilityFilter) : ListNotificationFilter {
+
+       /**
+        * Filters new-post and new-reply notifications in the given list of
+        * notifications. If `currentSone` is `null`, new-post and
+        * new-reply notifications are removed completely. If `currentSone` is
+        * not `null`, only posts that are posted by a friend Sone or the Sone
+        * itself, and replies that are replies to posts of friend Sones or the Sone
+        * itself will be retained in the notifications.
+        *
+        * @param notifications
+        * The notifications to filter
+        * @param currentSone
+        * The current Sone, or `null` if not logged in
+        * @return The filtered notifications
+        */
+       override fun filterNotifications(notifications: Collection<Notification>, currentSone: Sone?) =
+                       notifications.mapNotNull { it.filtered(currentSone) }
+
+       @Suppress("UNCHECKED_CAST")
+       private fun Notification.filtered(currentSone: Sone?): Notification? = when {
+               isNewSoneNotification -> {
+                       takeIf { currentSone == null || currentSone.options.isShowNewSoneNotifications }
+               }
+               isNewPostNotification -> {
+                       (currentSone != null && currentSone.options.isShowNewPostNotifications).ifTrue {
+                               (this as ListNotification<Post>).filterNotification { postVisibilityFilter.isPostVisible(currentSone, it) }
+                       }
+               }
+               isNewReplyNotification -> {
+                       (currentSone != null && currentSone.options.isShowNewReplyNotifications).ifTrue {
+                               (this as ListNotification<PostReply>).filterNotification { replyVisibilityFilter.isReplyVisible(currentSone, it) }
+                       }
+               }
+               isMentionNotification -> {
+                       (this as ListNotification<Post>).filterNotification { postVisibilityFilter.isPostVisible(currentSone, it) }
+               }
+               else -> this
+       }
+
+}
+
+/**
+ * Filters the elements of this list notification.
+ *
+ * @param filter The filter for the notification’s elements
+ * @return A list notification containing the filtered elements, or `null`
+ * if the notification does not have any elements after filtering
+ */
+private fun <T> ListNotification<T>.filterNotification(filter: (T) -> Boolean) =
+               elements.filter(filter).let { filteredElements ->
+                       when (filteredElements.size) {
+                               0 -> null
+                               elements.size -> this
+                               else -> ListNotification(this).apply {
+                                       setElements(filteredElements)
+                                       setLastUpdateTime(lastUpdatedTime)
+                               }
+                       }
+               }
index aedb180..63041f6 100644 (file)
  */
 package net.pterodactylus.sone.notify
 
-import net.pterodactylus.sone.data.Post
-import net.pterodactylus.sone.data.PostReply
+import com.google.inject.ImplementedBy
 import net.pterodactylus.sone.data.Sone
-import net.pterodactylus.sone.utils.ifTrue
 import net.pterodactylus.util.notify.Notification
-import javax.inject.Inject
-import javax.inject.Singleton
 
 /**
- * Filter for [ListNotification]s.
+ * Filters [list notifications][ListNotification], depending on the current
+ * [Sone] and [its options][Sone.getOptions].
  */
-@Singleton
-class ListNotificationFilter @Inject constructor(private val postVisibilityFilter: PostVisibilityFilter, private val replyVisibilityFilter: ReplyVisibilityFilter) {
+@ImplementedBy(DefaultListNotificationFilter::class)
+interface ListNotificationFilter {
 
-       /**
-        * Filters new-post and new-reply notifications in the given list of
-        * notifications. If `currentSone` is `null`, new-post and
-        * new-reply notifications are removed completely. If `currentSone` is
-        * not `null`, only posts that are posted by a friend Sone or the Sone
-        * itself, and replies that are replies to posts of friend Sones or the Sone
-        * itself will be retained in the notifications.
-        *
-        * @param notifications
-        * The notifications to filter
-        * @param currentSone
-        * The current Sone, or `null` if not logged in
-        * @return The filtered notifications
-        */
-       fun filterNotifications(notifications: Collection<Notification>, currentSone: Sone?) =
-                       notifications.mapNotNull { it.filtered(currentSone) }
-
-       @Suppress("UNCHECKED_CAST")
-       private fun Notification.filtered(currentSone: Sone?): Notification? = when {
-               isNewSoneNotification -> {
-                       takeIf { currentSone == null || currentSone.options.isShowNewSoneNotifications }
-               }
-               isNewPostNotification -> {
-                       (currentSone != null && currentSone.options.isShowNewPostNotifications).ifTrue {
-                               (this as ListNotification<Post>).filterNotification { postVisibilityFilter.isPostVisible(currentSone, it) }
-                       }
-               }
-               isNewReplyNotification -> {
-                       (currentSone != null && currentSone.options.isShowNewReplyNotifications).ifTrue {
-                               (this as ListNotification<PostReply>).filterNotification { replyVisibilityFilter.isReplyVisible(currentSone, it) }
-                       }
-               }
-               isMentionNotification -> {
-                       (this as ListNotification<Post>).filterNotification { postVisibilityFilter.isPostVisible(currentSone, it) }
-               }
-               else -> this
-       }
+       fun filterNotifications(notifications: Collection<Notification>, currentSone: Sone?): Collection<Notification>
 
 }
-
-/**
- * Filters the elements of this list notification.
- *
- * @param filter The filter for the notification’s elements
- * @return A list notification containing the filtered elements, or `null`
- * if the notification does not have any elements after filtering
- */
-private fun <T> ListNotification<T>.filterNotification(filter: (T) -> Boolean) =
-               elements.filter(filter).let { filteredElements ->
-                       when (filteredElements.size) {
-                               0 -> null
-                               elements.size -> this
-                               else -> ListNotification(this).apply {
-                                       setElements(filteredElements)
-                                       setLastUpdateTime(lastUpdatedTime)
-                               }
-                       }
-               }
index 67a01c3..ffc1e5a 100644 (file)
@@ -23,7 +23,7 @@ import org.junit.Test
  */
 class ListNotificationFilterTest {
 
-       private val listNotificationFilter = ListNotificationFilter(showAllPosts, showAllReplies)
+       private val listNotificationFilter = DefaultListNotificationFilter(showAllPosts, showAllReplies)
 
        @Test
        fun `filter is only created once`() {
@@ -72,7 +72,7 @@ class ListNotificationFilterTest {
                localSone.options.isShowNewPostNotifications = true
                val newPostNotification = createNewPostNotification()
                newPostNotification.add(createPost())
-               val listNotificationFilter = ListNotificationFilter(showNoPosts, showAllReplies)
+               val listNotificationFilter = DefaultListNotificationFilter(showNoPosts, showAllReplies)
                val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newPostNotification), localSone)
                assertThat(filteredNotifications, emptyIterable())
        }
@@ -104,7 +104,7 @@ class ListNotificationFilterTest {
                val newPostNotification = createNewPostNotification()
                newPostNotification.add(createPost())
                newPostNotification.add(createPost())
-               val listNotificationFilter = ListNotificationFilter(matchThisPost(newPostNotification.elements[1]), showAllReplies)
+               val listNotificationFilter = DefaultListNotificationFilter(matchThisPost(newPostNotification.elements[1]), showAllReplies)
                val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newPostNotification), localSone)
                assertThat((filteredNotifications[0] as ListNotification<Post>).elements, contains(newPostNotification.elements[1]))
        }
@@ -116,7 +116,7 @@ class ListNotificationFilterTest {
                val newReplyNotification = createNewReplyNotification()
                newReplyNotification.add(createPostReply())
                newReplyNotification.add(createPostReply())
-               val listNotificationFilter = ListNotificationFilter(showAllPosts, matchThisReply(newReplyNotification.elements[1]))
+               val listNotificationFilter = DefaultListNotificationFilter(showAllPosts, matchThisReply(newReplyNotification.elements[1]))
                val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newReplyNotification), localSone)
                assertThat(filteredNotifications, hasSize(1))
                assertThat((filteredNotifications[0] as ListNotification<PostReply?>).elements[0], equalTo(newReplyNotification.elements[1]))
@@ -140,7 +140,7 @@ class ListNotificationFilterTest {
                val newReplyNotification = createNewReplyNotification()
                newReplyNotification.add(createPostReply())
                newReplyNotification.add(createPostReply())
-               val listNotificationFilter = ListNotificationFilter(showAllPosts, showNoReplies)
+               val listNotificationFilter = DefaultListNotificationFilter(showAllPosts, showNoReplies)
                val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newReplyNotification), localSone)
                assertThat(filteredNotifications, emptyIterable())
        }
@@ -170,7 +170,7 @@ class ListNotificationFilterTest {
                val mentionNotification = createMentionNotification()
                mentionNotification.add(createPost())
                mentionNotification.add(createPost())
-               val listNotificationFilter = ListNotificationFilter(matchThisPost(mentionNotification.elements[1]), showAllReplies)
+               val listNotificationFilter = DefaultListNotificationFilter(matchThisPost(mentionNotification.elements[1]), showAllReplies)
                val filteredNotifications = listNotificationFilter.filterNotifications(listOf(mentionNotification), null)
                assertThat(filteredNotifications, hasSize(1))
                assertThat((filteredNotifications[0] as ListNotification<Post?>).elements[0], equalTo(mentionNotification.elements[1]))
@@ -181,7 +181,7 @@ class ListNotificationFilterTest {
                val mentionNotification = createMentionNotification()
                mentionNotification.add(createPost())
                mentionNotification.add(createPost())
-               val listNotificationFilter = ListNotificationFilter(showNoPosts, showAllReplies)
+               val listNotificationFilter = DefaultListNotificationFilter(showNoPosts, showAllReplies)
                val filteredNotifications = listNotificationFilter.filterNotifications(listOf(mentionNotification), null)
                assertThat(filteredNotifications, emptyIterable())
        }