🎨 Replace list notification filter test with Kotlin version
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 20 Jun 2020 12:16:36 +0000 (14:16 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 20 Jun 2020 12:16:36 +0000 (14:16 +0200)
src/test/java/net/pterodactylus/sone/notify/ListNotificationFilterTest.java [deleted file]
src/test/kotlin/net/pterodactylus/sone/notify/ListNotificationFilterTest.kt [new file with mode: 0644]

diff --git a/src/test/java/net/pterodactylus/sone/notify/ListNotificationFilterTest.java b/src/test/java/net/pterodactylus/sone/notify/ListNotificationFilterTest.java
deleted file mode 100644 (file)
index af6339b..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-package net.pterodactylus.sone.notify;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.emptyIterable;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.sameInstance;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.annotation.Nullable;
-
-import net.pterodactylus.sone.data.Post;
-import net.pterodactylus.sone.data.PostReply;
-import net.pterodactylus.sone.data.Sone;
-import net.pterodactylus.sone.data.SoneOptions;
-import net.pterodactylus.sone.freenet.wot.OwnIdentity;
-import net.pterodactylus.util.notify.Notification;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import org.hamcrest.Matchers;
-import org.junit.Test;
-import org.mockito.ArgumentMatchers;
-
-/**
- * Unit test for {@link ListNotificationFilterTest}.
- */
-public class ListNotificationFilterTest {
-
-       private static final String LOCAL_ID = "local-id";
-
-       private final PostVisibilityFilter postVisibilityFilter = mock(PostVisibilityFilter.class);
-       private final ReplyVisibilityFilter replyVisibilityFilter = mock(ReplyVisibilityFilter.class);
-       private final ListNotificationFilter listNotificationFilter = new ListNotificationFilter(postVisibilityFilter, replyVisibilityFilter);
-
-       private final Sone localSone = mock(Sone.class);
-       private final SoneOptions soneOptions = mock(SoneOptions.class);
-       private final OwnIdentity localIdentity = mock(OwnIdentity.class);
-       private final List<ListNotification<Post>> newPostNotifications = Arrays.asList(createNewPostNotification());
-       private final List<ListNotification<PostReply>> newReplyNotifications = Arrays.asList(createNewReplyNotification());
-       private final List<ListNotification<Post>> mentionNotifications = Arrays.asList(createMentionNotification());
-
-       public ListNotificationFilterTest() {
-               when(localSone.getId()).thenReturn(LOCAL_ID);
-               when(localSone.isLocal()).thenReturn(true);
-               when(localSone.getIdentity()).thenReturn(localIdentity);
-               when(localIdentity.getId()).thenReturn(LOCAL_ID);
-               when(localSone.getOptions()).thenReturn(soneOptions);
-       }
-
-       @Test
-       public void filterIsOnlyCreatedOnce() {
-           Injector injector = Guice.createInjector();
-               ListNotificationFilter firstFilter = injector.getInstance(ListNotificationFilter.class);
-               ListNotificationFilter secondFilter = injector.getInstance(ListNotificationFilter.class);
-               assertThat(firstFilter, sameInstance(secondFilter));
-       }
-
-       @Test
-       public void newSoneNotificationsAreNotRemovedIfNotLoggedIn() {
-               List<Notification> notifications = Arrays.asList(createNewSoneNotification());
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(notifications, null);
-               assertThat(filteredNotifications, contains(notifications.get(0)));
-       }
-
-       private Notification createNewSoneNotification() {
-               ListNotification<Sone> newSoneNotification = mock(ListNotification.class);
-               when(newSoneNotification.getId()).thenReturn("new-sone-notification");
-               return newSoneNotification;
-       }
-
-       @Test
-       public void newSoneNotificationsAreRemovedIfLoggedInAndNewSonesShouldNotBeShown() {
-               List<Notification> notifications = Arrays.asList(createNewSoneNotification());
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(notifications, localSone);
-               assertThat(filteredNotifications, emptyIterable());
-       }
-
-       @Test
-       public void newSoneNotificationsAreNotRemovedIfLoggedInAndNewSonesShouldBeShown() {
-               List<Notification> notifications = Arrays.asList(createNewSoneNotification());
-               when(soneOptions.isShowNewSoneNotifications()).thenReturn(true);
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(notifications, localSone);
-               assertThat(filteredNotifications, contains(notifications.get(0)));
-       }
-
-       private ListNotification<Post> createNewPostNotification() {
-               ListNotification<Post> newSoneNotification = mock(ListNotification.class);
-               when(newSoneNotification.getElements()).thenReturn(new ArrayList<Post>());
-               when(newSoneNotification.getId()).thenReturn("new-post-notification");
-               return newSoneNotification;
-       }
-
-       @Test
-       public void newPostNotificationIsNotShownIfOptionsSetAccordingly() {
-               List<ListNotification<Post>> notifications = Arrays.asList(createNewPostNotification());
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(notifications, localSone);
-               assertThat(filteredNotifications, hasSize(0));
-       }
-
-       private void activateNewPostNotifications() {
-               when(soneOptions.isShowNewPostNotifications()).thenReturn(true);
-       }
-
-       private boolean addPostToPostNotification(List<ListNotification<Post>> notifications) {
-               return notifications.get(0).getElements().add(mock(Post.class));
-       }
-
-       private void setPostVisibilityPredicate(Predicate<Post> value) {
-               when(postVisibilityFilter.isVisible(ArgumentMatchers.<Sone>any())).thenReturn(value);
-       }
-
-       @Test
-       public void newPostNotificationIsNotShownIfNoNewPostsAreVisible() {
-               activateNewPostNotifications();
-               addPostToPostNotification(newPostNotifications);
-               setPostVisibilityPredicate(Predicates.<Post>alwaysFalse());
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newPostNotifications, localSone);
-               assertThat(filteredNotifications, hasSize(0));
-       }
-
-       @Test
-       public void newPostNotificationIsShownIfNewPostsAreVisible() {
-               activateNewPostNotifications();
-               addPostToPostNotification(newPostNotifications);
-               setPostVisibilityPredicate(Predicates.<Post>alwaysTrue());
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newPostNotifications, localSone);
-               assertThat(filteredNotifications, contains((Notification) newPostNotifications.get(0)));
-       }
-
-       @Test
-       public void newPostNotificationIsNotShownIfNewPostsAreVisibleButLocalSoneIsNull() {
-               activateNewPostNotifications();
-               addPostToPostNotification(newPostNotifications);
-               setPostVisibilityPredicate(Predicates.<Post>alwaysTrue());
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newPostNotifications, null);
-               assertThat(filteredNotifications, Matchers.<Notification>emptyIterable());
-       }
-
-       @Test
-       public void newPostNotificationContainsOnlyVisiblePosts() {
-               activateNewPostNotifications();
-               addPostToPostNotification(newPostNotifications);
-               addPostToPostNotification(newPostNotifications);
-               setPostVisibilityPredicate(new Predicate<Post>() {
-                       @Override
-                       public boolean apply(@Nullable Post post) {
-                               return post.equals(newPostNotifications.get(0).getElements().get(1));
-                       }
-               });
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newPostNotifications, localSone);
-               assertThat(filteredNotifications, hasSize(1));
-               assertThat(((ListNotification<Post>) filteredNotifications.get(0)).getElements().get(0), is(newPostNotifications.get(0).getElements().get(1)));
-       }
-
-       private ListNotification<PostReply> createNewReplyNotification() {
-               ListNotification<PostReply> newReplyNotifications = mock(ListNotification.class);
-               when(newReplyNotifications.getElements()).thenReturn(new ArrayList<PostReply>());
-               when(newReplyNotifications.getId()).thenReturn("new-reply-notification");
-               return newReplyNotifications;
-       }
-
-       private void activateNewReplyNotifications() {
-               when(soneOptions.isShowNewReplyNotifications()).thenReturn(true);
-       }
-
-       private void addReplyToNewReplyNotification(List<ListNotification<PostReply>> notifications) {
-               notifications.get(0).getElements().add(mock(PostReply.class));
-       }
-
-       private void setReplyVisibilityPredicate(Predicate<PostReply> value) {
-               when(replyVisibilityFilter.isVisible(any(Sone.class))).thenReturn(value);
-       }
-
-       @Test
-       public void newReplyNotificationContainsOnlyVisibleReplies() {
-               activateNewReplyNotifications();
-               addReplyToNewReplyNotification(newReplyNotifications);
-               addReplyToNewReplyNotification(newReplyNotifications);
-               setReplyVisibilityPredicate(new Predicate<PostReply>() {
-                       @Override
-                       public boolean apply(@Nullable PostReply postReply) {
-                               return postReply.equals(newReplyNotifications.get(0).getElements().get(1));
-                       }
-               });
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newReplyNotifications, localSone);
-               assertThat(filteredNotifications, hasSize(1));
-               assertThat(((ListNotification<PostReply>) filteredNotifications.get(0)).getElements().get(0), is(newReplyNotifications.get(0).getElements().get(1)));
-       }
-
-       @Test
-       public void newReplyNotificationIsNotModifiedIfAllRepliesAreVisible() {
-               activateNewReplyNotifications();
-               addReplyToNewReplyNotification(newReplyNotifications);
-               addReplyToNewReplyNotification(newReplyNotifications);
-               setReplyVisibilityPredicate(Predicates.<PostReply>alwaysTrue());
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newReplyNotifications, localSone);
-               assertThat(filteredNotifications, hasSize(1));
-               assertThat(filteredNotifications.get(0), is((Notification) newReplyNotifications.get(0)));
-               assertThat(((ListNotification<PostReply>) filteredNotifications.get(0)).getElements(), hasSize(2));
-       }
-
-       @Test
-       public void newReplyNotificationIsNotShownIfNoRepliesAreVisible() {
-               activateNewReplyNotifications();
-               addReplyToNewReplyNotification(newReplyNotifications);
-               addReplyToNewReplyNotification(newReplyNotifications);
-               setReplyVisibilityPredicate(Predicates.<PostReply>alwaysFalse());
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newReplyNotifications, localSone);
-               assertThat(filteredNotifications, hasSize(0));
-       }
-
-       @Test
-       public void newReplyNotificationIsNotShownIfDeactivatedInOptions() {
-               addReplyToNewReplyNotification(newReplyNotifications);
-               addReplyToNewReplyNotification(newReplyNotifications);
-               setReplyVisibilityPredicate(Predicates.<PostReply>alwaysTrue());
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newReplyNotifications, localSone);
-               assertThat(filteredNotifications, hasSize(0));
-       }
-
-       @Test
-       public void newReplyNotificationIsNotShownIfCurrentSoneIsNull() {
-               addReplyToNewReplyNotification(newReplyNotifications);
-               addReplyToNewReplyNotification(newReplyNotifications);
-               setReplyVisibilityPredicate(Predicates.<PostReply>alwaysTrue());
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newReplyNotifications, null);
-               assertThat(filteredNotifications, hasSize(0));
-       }
-
-       private ListNotification<Post> createMentionNotification() {
-               ListNotification<Post> newSoneNotification = mock(ListNotification.class);
-               when(newSoneNotification.getElements()).thenReturn(new ArrayList<Post>());
-               when(newSoneNotification.getId()).thenReturn("mention-notification");
-               return newSoneNotification;
-       }
-
-       @Test
-       public void mentionNotificationContainsOnlyVisiblePosts() {
-               addPostToPostNotification(mentionNotifications);
-               addPostToPostNotification(mentionNotifications);
-               setPostVisibilityPredicate(new Predicate<Post>() {
-                       @Override
-                       public boolean apply(@Nullable Post post) {
-                               return post.equals(mentionNotifications.get(0).getElements().get(1));
-                       }
-               });
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(mentionNotifications, localSone);
-               assertThat(filteredNotifications, hasSize(1));
-               assertThat(((ListNotification<Post>) filteredNotifications.get(0)).getElements().get(0), is(mentionNotifications.get(0).getElements().get(1)));
-       }
-
-       @Test
-       public void mentionNotificationIsNotShownIfNoPostsAreVisible() {
-               addPostToPostNotification(mentionNotifications);
-               addPostToPostNotification(mentionNotifications);
-               setPostVisibilityPredicate(Predicates.<Post>alwaysFalse());
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(mentionNotifications, localSone);
-               assertThat(filteredNotifications, hasSize(0));
-       }
-
-       @Test
-       public void unfilterableNotificationIsNotFiltered() {
-               Notification notification = mock(Notification.class);
-               when(notification.getId()).thenReturn("random-notification");
-               List<Notification> notifications = Arrays.asList(notification);
-               List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(notifications, null);
-               assertThat(filteredNotifications, contains(notification));
-       }
-
-}
diff --git a/src/test/kotlin/net/pterodactylus/sone/notify/ListNotificationFilterTest.kt b/src/test/kotlin/net/pterodactylus/sone/notify/ListNotificationFilterTest.kt
new file mode 100644 (file)
index 0000000..e552ece
--- /dev/null
@@ -0,0 +1,228 @@
+package net.pterodactylus.sone.notify
+
+import com.google.common.base.Predicate
+import com.google.inject.Guice
+import net.pterodactylus.sone.data.Post
+import net.pterodactylus.sone.data.PostReply
+import net.pterodactylus.sone.data.Sone
+import net.pterodactylus.sone.test.createLocalSone
+import net.pterodactylus.sone.test.createPost
+import net.pterodactylus.sone.test.createPostReply
+import net.pterodactylus.sone.test.verifySingletonInstance
+import net.pterodactylus.util.notify.Notification
+import net.pterodactylus.util.notify.TemplateNotification
+import net.pterodactylus.util.template.Template
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.contains
+import org.hamcrest.Matchers.emptyIterable
+import org.hamcrest.Matchers.equalTo
+import org.hamcrest.Matchers.hasSize
+import org.junit.Test
+
+/**
+ * Unit test for [ListNotificationFilterTest].
+ */
+class ListNotificationFilterTest {
+
+       private val listNotificationFilter = ListNotificationFilter(showAllPosts, showAllReplies)
+
+       @Test
+       fun `filter is only created once`() {
+               val injector = Guice.createInjector()
+               injector.verifySingletonInstance<ListNotificationFilter>()
+       }
+
+       @Test
+       fun `new sone notifications are not removed if not logged in`() {
+               val notification = createNewSoneNotification()
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(notification), null)
+               assertThat(filteredNotifications, contains<Notification>(notification))
+       }
+
+       @Test
+       fun `new sone notifications are removed if logged in and new sones should not be shown`() {
+               val notification = createNewSoneNotification()
+               val localSone = createLocalSone()
+               localSone.options.isShowNewSoneNotifications = false
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(notification), localSone)
+               assertThat(filteredNotifications, emptyIterable())
+       }
+
+       @Test
+       fun `new sone notifications are not removed if logged in and new sones should be shown`() {
+               val notification = createNewSoneNotification()
+               val localSone = createLocalSone()
+               localSone.options.isShowNewSoneNotifications = true
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(notification), localSone)
+               assertThat(filteredNotifications, contains<Notification>(notification))
+       }
+
+       @Test
+       fun `new post notification is not shown if options set accordingly`() {
+               val newPostNotification = createNewPostNotification()
+               newPostNotification.add(createPost())
+               val localSone = createLocalSone()
+               localSone.options.isShowNewPostNotifications = false
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newPostNotification), localSone)
+               assertThat(filteredNotifications, emptyIterable())
+       }
+
+       @Test
+       fun `new post notification is not shown if no new posts are visible`() {
+               val localSone = createLocalSone()
+               localSone.options.isShowNewPostNotifications = true
+               val newPostNotification = createNewPostNotification()
+               newPostNotification.add(createPost())
+               val listNotificationFilter = ListNotificationFilter(showNoPosts, showAllReplies)
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newPostNotification), localSone)
+               assertThat(filteredNotifications, emptyIterable())
+       }
+
+       @Test
+       fun `new post notification is shown if new posts are visible`() {
+               val localSone = createLocalSone()
+               localSone.options.isShowNewPostNotifications = true
+               val newPostNotification = createNewPostNotification()
+               newPostNotification.add(createPost())
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newPostNotification), localSone)
+               assertThat(filteredNotifications, contains<Notification>(newPostNotification))
+       }
+
+       @Test
+       fun `new post notification is not shown if new posts are visible but local sone is null`() {
+               val localSone = createLocalSone()
+               localSone.options.isShowNewPostNotifications = true
+               val newPostNotification = createNewPostNotification()
+               newPostNotification.add(createPost())
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newPostNotification), null)
+               assertThat(filteredNotifications, emptyIterable())
+       }
+
+       @Test
+       fun `new post notification contains only visible posts`() {
+               val localSone = createLocalSone()
+               localSone.options.isShowNewPostNotifications = true
+               val newPostNotification = createNewPostNotification()
+               newPostNotification.add(createPost())
+               newPostNotification.add(createPost())
+               val listNotificationFilter = ListNotificationFilter(matchThisPost(newPostNotification.elements[1]), showAllReplies)
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newPostNotification), localSone)
+               assertThat((filteredNotifications[0] as ListNotification<Post>).elements, contains(newPostNotification.elements[1]))
+       }
+
+       @Test
+       fun `new reply notification contains only visible replies`() {
+               val localSone = createLocalSone()
+               localSone.options.isShowNewReplyNotifications = true
+               val newReplyNotification = createNewReplyNotification()
+               newReplyNotification.add(createPostReply())
+               newReplyNotification.add(createPostReply())
+               val listNotificationFilter = ListNotificationFilter(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]))
+       }
+
+       @Test
+       fun `new reply notification is not modified if all replies are visible`() {
+               val localSone = createLocalSone()
+               localSone.options.isShowNewReplyNotifications = true
+               val newReplyNotification = createNewReplyNotification()
+               newReplyNotification.add(createPostReply())
+               newReplyNotification.add(createPostReply())
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newReplyNotification), localSone)
+               assertThat(filteredNotifications, contains<Notification>(newReplyNotification))
+       }
+
+       @Test
+       fun `new reply notification is not shown if no replies are visible`() {
+               val localSone = createLocalSone()
+               localSone.options.isShowNewReplyNotifications = true
+               val newReplyNotification = createNewReplyNotification()
+               newReplyNotification.add(createPostReply())
+               newReplyNotification.add(createPostReply())
+               val listNotificationFilter = ListNotificationFilter(showAllPosts, showNoReplies)
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newReplyNotification), localSone)
+               assertThat(filteredNotifications, emptyIterable())
+       }
+
+       @Test
+       fun `new reply notification is not shown if deactivated in options`() {
+               val localSone = createLocalSone()
+               localSone.options.isShowNewReplyNotifications = false
+               val newReplyNotification = createNewReplyNotification()
+               newReplyNotification.add(createPostReply())
+               newReplyNotification.add(createPostReply())
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newReplyNotification), localSone)
+               assertThat(filteredNotifications, emptyIterable())
+       }
+
+       @Test
+       fun `new reply notification is not shown if current sone is null`() {
+               val newReplyNotification = createNewReplyNotification()
+               newReplyNotification.add(createPostReply())
+               newReplyNotification.add(createPostReply())
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(newReplyNotification), null)
+               assertThat(filteredNotifications, emptyIterable())
+       }
+
+       @Test
+       fun `mention notification contains only visible posts`() {
+               val mentionNotification = createMentionNotification()
+               mentionNotification.add(createPost())
+               mentionNotification.add(createPost())
+               val listNotificationFilter = ListNotificationFilter(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]))
+       }
+
+       @Test
+       fun `mention notification is not shown if no posts are visible`() {
+               val mentionNotification = createMentionNotification()
+               mentionNotification.add(createPost())
+               mentionNotification.add(createPost())
+               val listNotificationFilter = ListNotificationFilter(showNoPosts, showAllReplies)
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(mentionNotification), null)
+               assertThat(filteredNotifications, emptyIterable())
+       }
+
+
+       @Test
+       fun `unfilterable notification is not filtered`() {
+               val notification: Notification = TemplateNotification("random-notification", Template())
+               val filteredNotifications = listNotificationFilter.filterNotifications(listOf(notification), null)
+               assertThat(filteredNotifications, contains(notification))
+       }
+
+}
+
+private fun createNewSoneNotification() =
+               ListNotification<Sone>("new-sone-notification", "", Template())
+
+private fun createNewPostNotification() =
+               ListNotification<Post>("new-post-notification", "", Template())
+
+private fun createNewReplyNotification() =
+               ListNotification<PostReply>("new-reply-notification", "", Template())
+
+private fun createMentionNotification() =
+               ListNotification<Post>("mention-notification", "", Template())
+
+private fun matchThisPost(post: Post) = createPostVisibilityFilter { _, p -> p == post }
+private val showAllPosts = createPostVisibilityFilter { _, _ -> true }
+private val showNoPosts = createPostVisibilityFilter { _, _ -> false }
+
+private fun createPostVisibilityFilter(visible: (Sone?, Post) -> Boolean) = object : PostVisibilityFilter() {
+       override fun isPostVisible(sone: Sone?, post: Post) = visible(sone, post)
+       override fun isVisible(currentSone: Sone?) = Predicate<Post> { p -> p != null && isPostVisible(currentSone, p) }
+}
+
+private fun matchThisReply(reply: PostReply) = createReplyVisibilityFilter(showAllPosts) { _, r -> r == reply }
+private val showAllReplies = createReplyVisibilityFilter(showAllPosts) { _, _ -> true }
+private val showNoReplies = createReplyVisibilityFilter(showAllPosts) { _, _ -> false }
+
+private fun createReplyVisibilityFilter(postVisibilityFilter: PostVisibilityFilter, visible: (Sone?, PostReply) -> Boolean) = object : ReplyVisibilityFilter(postVisibilityFilter) {
+       override fun isReplyVisible(sone: Sone?, reply: PostReply) = visible(sone, reply)
+       override fun isVisible(currentSone: Sone?) = Predicate<PostReply> { r -> r != null && isReplyVisible(currentSone, r) }
+}