diff --git a/mastodon/src/androidTest/java/org/joinmastodon/android/utils/StatusFilterPredicateTest.java b/mastodon/src/androidTest/java/org/joinmastodon/android/utils/StatusFilterPredicateTest.java new file mode 100644 index 000000000..0a00fc665 --- /dev/null +++ b/mastodon/src/androidTest/java/org/joinmastodon/android/utils/StatusFilterPredicateTest.java @@ -0,0 +1,81 @@ +package org.joinmastodon.android.utils; + +import static org.joinmastodon.android.model.Filter.FilterAction.*; +import static org.joinmastodon.android.model.Filter.FilterContext.*; +import static org.junit.Assert.*; + +import org.joinmastodon.android.model.Filter; +import org.joinmastodon.android.model.Status; +import org.junit.Test; + +import java.time.Instant; +import java.util.EnumSet; +import java.util.List; + +public class StatusFilterPredicateTest { + + private static final Filter hideMeFilter = new Filter(), warnMeFilter = new Filter(); + private static final List allFilters = List.of(hideMeFilter, warnMeFilter); + + private static final Status + hideInHomePublic = Status.ofFake(null, "hide me, please", Instant.now()), + warnInHomePublic = Status.ofFake(null, "display me with a warning", Instant.now()); + + static { + hideMeFilter.phrase = "hide me"; + hideMeFilter.filterAction = HIDE; + hideMeFilter.context = EnumSet.of(PUBLIC, HOME); + + warnMeFilter.phrase = "warning"; + warnMeFilter.filterAction = WARN; + warnMeFilter.context = EnumSet.of(PUBLIC, HOME); + } + + @Test + public void testHide() { + assertFalse("should not pass because matching filter applies to given context", + new StatusFilterPredicate(allFilters, HOME).test(hideInHomePublic)); + } + + @Test + public void testHideRegardlessOfContext() { + assertTrue("filters without context should always pass", + new StatusFilterPredicate(allFilters, null).test(hideInHomePublic)); + } + + @Test + public void testHideInDifferentContext() { + assertTrue("should pass because matching filter does not apply to given context", + new StatusFilterPredicate(allFilters, THREAD).test(hideInHomePublic)); + } + + @Test + public void testHideWithWarningText() { + assertTrue("should pass because matching filter is for warnings", + new StatusFilterPredicate(allFilters, HOME).test(warnInHomePublic)); + } + + @Test + public void testWarn() { + assertFalse("should not pass because filter applies to given context", + new StatusFilterPredicate(allFilters, HOME, WARN).test(warnInHomePublic)); + } + + @Test + public void testWarnRegardlessOfContext() { + assertTrue("filters without context should always pass", + new StatusFilterPredicate(allFilters, null, WARN).test(warnInHomePublic)); + } + + @Test + public void testWarnInDifferentContext() { + assertTrue("should pass because filter does not apply to given context", + new StatusFilterPredicate(allFilters, THREAD, WARN).test(warnInHomePublic)); + } + + @Test + public void testWarnWithHideText() { + assertTrue("should pass because matching filter is for hiding", + new StatusFilterPredicate(allFilters, HOME, WARN).test(hideInHomePublic)); + } +} \ No newline at end of file diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/Status.java b/mastodon/src/main/java/org/joinmastodon/android/model/Status.java index 156a3d874..8df45b976 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/Status.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/Status.java @@ -50,6 +50,8 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{ public long favouritesCount; public long repliesCount; public Instant editedAt; + // might not be provided (by older mastodon servers), + // so megalodon will use the locally cached filters if filtered == null public List filtered; public String url; @@ -180,7 +182,6 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{ s.mentions = List.of(); s.tags = List.of(); s.emojis = List.of(); - s.filtered = List.of(); return s; } diff --git a/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java b/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java index 7193b5c11..8c73d3a87 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java +++ b/mastodon/src/main/java/org/joinmastodon/android/utils/StatusFilterPredicate.java @@ -17,11 +17,28 @@ public class StatusFilterPredicate implements Predicate{ /** * @param context null makes the predicate pass automatically + * @param action defines what the predicate should check: + * status should not be hidden or should not display with warning */ - public StatusFilterPredicate(List filters, Filter.FilterContext context){ - this.filters=filters; + public StatusFilterPredicate(List filters, Filter.FilterContext context, Filter.FilterAction action){ + this.filters = filters; this.context = context; - this.action = Filter.FilterAction.HIDE; + this.action = action; + } + + public StatusFilterPredicate(List filters, Filter.FilterContext context){ + this(filters, context, Filter.FilterAction.HIDE); + } + + /** + * @param context null makes the predicate pass automatically + * @param action defines what the predicate should check: + * status should not be hidden or should not display with warning + */ + public StatusFilterPredicate(String accountID, Filter.FilterContext context, Filter.FilterAction action){ + filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(context)).collect(Collectors.toList()); + this.context = context; + this.action = action; } /** @@ -32,16 +49,11 @@ public class StatusFilterPredicate implements Predicate{ } /** - * @param context null makes the predicate pass automatically - * @param action defines what the predicate should check: - * should not be hidden or should not display with warning + * @return whether the status should be displayed without being hidden/warned about. + * will always return true if the context is null. + * true = display this status, + * false = filter this status */ - public StatusFilterPredicate(String accountID, Filter.FilterContext context, Filter.FilterAction action){ - filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(context)).collect(Collectors.toList()); - this.context = context; - this.action = action; - } - @Override public boolean test(Status status){ if (context == null) return true;