dabfd5a6a7d01683ce070c111123a2bebac40613
[Sone.git] / src / test / java / net / pterodactylus / sone / notify / ListNotificationFilterTest.java
1 package net.pterodactylus.sone.notify;
2
3 import static org.hamcrest.MatcherAssert.assertThat;
4 import static org.hamcrest.Matchers.contains;
5 import static org.hamcrest.Matchers.emptyIterable;
6 import static org.hamcrest.Matchers.hasSize;
7 import static org.hamcrest.Matchers.is;
8 import static org.hamcrest.Matchers.sameInstance;
9 import static org.mockito.ArgumentMatchers.any;
10 import static org.mockito.Mockito.mock;
11 import static org.mockito.Mockito.when;
12
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.List;
16
17 import javax.annotation.Nullable;
18
19 import net.pterodactylus.sone.data.Post;
20 import net.pterodactylus.sone.data.PostReply;
21 import net.pterodactylus.sone.data.Sone;
22 import net.pterodactylus.sone.data.SoneOptions;
23 import net.pterodactylus.sone.freenet.wot.OwnIdentity;
24 import net.pterodactylus.util.notify.Notification;
25
26 import com.google.common.base.Predicate;
27 import com.google.common.base.Predicates;
28 import com.google.inject.Guice;
29 import com.google.inject.Injector;
30 import org.hamcrest.Matchers;
31 import org.junit.Test;
32 import org.mockito.ArgumentMatchers;
33
34 /**
35  * Unit test for {@link ListNotificationFilterTest}.
36  *
37  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
38  */
39 public class ListNotificationFilterTest {
40
41         private static final String LOCAL_ID = "local-id";
42
43         private final PostVisibilityFilter postVisibilityFilter = mock(PostVisibilityFilter.class);
44         private final ReplyVisibilityFilter replyVisibilityFilter = mock(ReplyVisibilityFilter.class);
45         private final ListNotificationFilter listNotificationFilter = new ListNotificationFilter(postVisibilityFilter, replyVisibilityFilter);
46
47         private final Sone localSone = mock(Sone.class);
48         private final SoneOptions soneOptions = mock(SoneOptions.class);
49         private final OwnIdentity localIdentity = mock(OwnIdentity.class);
50         private final List<ListNotification<Post>> newPostNotifications = Arrays.asList(createNewPostNotification());
51         private final List<ListNotification<PostReply>> newReplyNotifications = Arrays.asList(createNewReplyNotification());
52         private final List<ListNotification<Post>> mentionNotifications = Arrays.asList(createMentionNotification());
53
54         public ListNotificationFilterTest() {
55                 when(localSone.getId()).thenReturn(LOCAL_ID);
56                 when(localSone.isLocal()).thenReturn(true);
57                 when(localSone.getIdentity()).thenReturn(localIdentity);
58                 when(localIdentity.getId()).thenReturn(LOCAL_ID);
59                 when(localSone.getOptions()).thenReturn(soneOptions);
60         }
61
62         @Test
63         public void filterIsOnlyCreatedOnce() {
64             Injector injector = Guice.createInjector();
65                 ListNotificationFilter firstFilter = injector.getInstance(ListNotificationFilter.class);
66                 ListNotificationFilter secondFilter = injector.getInstance(ListNotificationFilter.class);
67                 assertThat(firstFilter, sameInstance(secondFilter));
68         }
69
70         @Test
71         public void newSoneNotificationsAreNotRemovedIfNotLoggedIn() {
72                 List<Notification> notifications = Arrays.asList(createNewSoneNotification());
73                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(notifications, null);
74                 assertThat(filteredNotifications, contains(notifications.get(0)));
75         }
76
77         private Notification createNewSoneNotification() {
78                 ListNotification<Sone> newSoneNotification = mock(ListNotification.class);
79                 when(newSoneNotification.getId()).thenReturn("new-sone-notification");
80                 return newSoneNotification;
81         }
82
83         @Test
84         public void newSoneNotificationsAreRemovedIfLoggedInAndNewSonesShouldNotBeShown() {
85                 List<Notification> notifications = Arrays.asList(createNewSoneNotification());
86                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(notifications, localSone);
87                 assertThat(filteredNotifications, emptyIterable());
88         }
89
90         @Test
91         public void newSoneNotificationsAreNotRemovedIfLoggedInAndNewSonesShouldBeShown() {
92                 List<Notification> notifications = Arrays.asList(createNewSoneNotification());
93                 when(soneOptions.isShowNewSoneNotifications()).thenReturn(true);
94                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(notifications, localSone);
95                 assertThat(filteredNotifications, contains(notifications.get(0)));
96         }
97
98         private ListNotification<Post> createNewPostNotification() {
99                 ListNotification<Post> newSoneNotification = mock(ListNotification.class);
100                 when(newSoneNotification.getElements()).thenReturn(new ArrayList<Post>());
101                 when(newSoneNotification.getId()).thenReturn("new-post-notification");
102                 return newSoneNotification;
103         }
104
105         @Test
106         public void newPostNotificationIsNotShownIfOptionsSetAccordingly() {
107                 List<ListNotification<Post>> notifications = Arrays.asList(createNewPostNotification());
108                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(notifications, localSone);
109                 assertThat(filteredNotifications, hasSize(0));
110         }
111
112         private void activateNewPostNotifications() {
113                 when(soneOptions.isShowNewPostNotifications()).thenReturn(true);
114         }
115
116         private boolean addPostToPostNotification(List<ListNotification<Post>> notifications) {
117                 return notifications.get(0).getElements().add(mock(Post.class));
118         }
119
120         private void setPostVisibilityPredicate(Predicate<Post> value) {
121                 when(postVisibilityFilter.isVisible(ArgumentMatchers.<Sone>any())).thenReturn(value);
122         }
123
124         @Test
125         public void newPostNotificationIsNotShownIfNoNewPostsAreVisible() {
126                 activateNewPostNotifications();
127                 addPostToPostNotification(newPostNotifications);
128                 setPostVisibilityPredicate(Predicates.<Post>alwaysFalse());
129                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newPostNotifications, localSone);
130                 assertThat(filteredNotifications, hasSize(0));
131         }
132
133         @Test
134         public void newPostNotificationIsShownIfNewPostsAreVisible() {
135                 activateNewPostNotifications();
136                 addPostToPostNotification(newPostNotifications);
137                 setPostVisibilityPredicate(Predicates.<Post>alwaysTrue());
138                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newPostNotifications, localSone);
139                 assertThat(filteredNotifications, contains((Notification) newPostNotifications.get(0)));
140         }
141
142         @Test
143         public void newPostNotificationIsNotShownIfNewPostsAreVisibleButLocalSoneIsNull() {
144                 activateNewPostNotifications();
145                 addPostToPostNotification(newPostNotifications);
146                 setPostVisibilityPredicate(Predicates.<Post>alwaysTrue());
147                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newPostNotifications, null);
148                 assertThat(filteredNotifications, Matchers.<Notification>emptyIterable());
149         }
150
151         @Test
152         public void newPostNotificationContainsOnlyVisiblePosts() {
153                 activateNewPostNotifications();
154                 addPostToPostNotification(newPostNotifications);
155                 addPostToPostNotification(newPostNotifications);
156                 setPostVisibilityPredicate(new Predicate<Post>() {
157                         @Override
158                         public boolean apply(@Nullable Post post) {
159                                 return post.equals(newPostNotifications.get(0).getElements().get(1));
160                         }
161                 });
162                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newPostNotifications, localSone);
163                 assertThat(filteredNotifications, hasSize(1));
164                 assertThat(((ListNotification<Post>) filteredNotifications.get(0)).getElements().get(0), is(newPostNotifications.get(0).getElements().get(1)));
165         }
166
167         private ListNotification<PostReply> createNewReplyNotification() {
168                 ListNotification<PostReply> newReplyNotifications = mock(ListNotification.class);
169                 when(newReplyNotifications.getElements()).thenReturn(new ArrayList<PostReply>());
170                 when(newReplyNotifications.getId()).thenReturn("new-reply-notification");
171                 return newReplyNotifications;
172         }
173
174         private void activateNewReplyNotifications() {
175                 when(soneOptions.isShowNewReplyNotifications()).thenReturn(true);
176         }
177
178         private void addReplyToNewReplyNotification(List<ListNotification<PostReply>> notifications) {
179                 notifications.get(0).getElements().add(mock(PostReply.class));
180         }
181
182         private void setReplyVisibilityPredicate(Predicate<PostReply> value) {
183                 when(replyVisibilityFilter.isVisible(any(Sone.class))).thenReturn(value);
184         }
185
186         @Test
187         public void newReplyNotificationContainsOnlyVisibleReplies() {
188                 activateNewReplyNotifications();
189                 addReplyToNewReplyNotification(newReplyNotifications);
190                 addReplyToNewReplyNotification(newReplyNotifications);
191                 setReplyVisibilityPredicate(new Predicate<PostReply>() {
192                         @Override
193                         public boolean apply(@Nullable PostReply postReply) {
194                                 return postReply.equals(newReplyNotifications.get(0).getElements().get(1));
195                         }
196                 });
197                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newReplyNotifications, localSone);
198                 assertThat(filteredNotifications, hasSize(1));
199                 assertThat(((ListNotification<PostReply>) filteredNotifications.get(0)).getElements().get(0), is(newReplyNotifications.get(0).getElements().get(1)));
200         }
201
202         @Test
203         public void newReplyNotificationIsNotModifiedIfAllRepliesAreVisible() {
204                 activateNewReplyNotifications();
205                 addReplyToNewReplyNotification(newReplyNotifications);
206                 addReplyToNewReplyNotification(newReplyNotifications);
207                 setReplyVisibilityPredicate(Predicates.<PostReply>alwaysTrue());
208                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newReplyNotifications, localSone);
209                 assertThat(filteredNotifications, hasSize(1));
210                 assertThat(filteredNotifications.get(0), is((Notification) newReplyNotifications.get(0)));
211                 assertThat(((ListNotification<PostReply>) filteredNotifications.get(0)).getElements(), hasSize(2));
212         }
213
214         @Test
215         public void newReplyNotificationIsNotShownIfNoRepliesAreVisible() {
216                 activateNewReplyNotifications();
217                 addReplyToNewReplyNotification(newReplyNotifications);
218                 addReplyToNewReplyNotification(newReplyNotifications);
219                 setReplyVisibilityPredicate(Predicates.<PostReply>alwaysFalse());
220                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newReplyNotifications, localSone);
221                 assertThat(filteredNotifications, hasSize(0));
222         }
223
224         @Test
225         public void newReplyNotificationIsNotShownIfDeactivatedInOptions() {
226                 addReplyToNewReplyNotification(newReplyNotifications);
227                 addReplyToNewReplyNotification(newReplyNotifications);
228                 setReplyVisibilityPredicate(Predicates.<PostReply>alwaysTrue());
229                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newReplyNotifications, localSone);
230                 assertThat(filteredNotifications, hasSize(0));
231         }
232
233         @Test
234         public void newReplyNotificationIsNotShownIfCurrentSoneIsNull() {
235                 addReplyToNewReplyNotification(newReplyNotifications);
236                 addReplyToNewReplyNotification(newReplyNotifications);
237                 setReplyVisibilityPredicate(Predicates.<PostReply>alwaysTrue());
238                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(newReplyNotifications, null);
239                 assertThat(filteredNotifications, hasSize(0));
240         }
241
242         private ListNotification<Post> createMentionNotification() {
243                 ListNotification<Post> newSoneNotification = mock(ListNotification.class);
244                 when(newSoneNotification.getElements()).thenReturn(new ArrayList<Post>());
245                 when(newSoneNotification.getId()).thenReturn("mention-notification");
246                 return newSoneNotification;
247         }
248
249         @Test
250         public void mentionNotificationContainsOnlyVisiblePosts() {
251                 addPostToPostNotification(mentionNotifications);
252                 addPostToPostNotification(mentionNotifications);
253                 setPostVisibilityPredicate(new Predicate<Post>() {
254                         @Override
255                         public boolean apply(@Nullable Post post) {
256                                 return post.equals(mentionNotifications.get(0).getElements().get(1));
257                         }
258                 });
259                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(mentionNotifications, localSone);
260                 assertThat(filteredNotifications, hasSize(1));
261                 assertThat(((ListNotification<Post>) filteredNotifications.get(0)).getElements().get(0), is(mentionNotifications.get(0).getElements().get(1)));
262         }
263
264         @Test
265         public void mentionNotificationIsNotShownIfNoPostsAreVisible() {
266                 addPostToPostNotification(mentionNotifications);
267                 addPostToPostNotification(mentionNotifications);
268                 setPostVisibilityPredicate(Predicates.<Post>alwaysFalse());
269                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(mentionNotifications, localSone);
270                 assertThat(filteredNotifications, hasSize(0));
271         }
272
273         @Test
274         public void unfilterableNotificationIsNotFiltered() {
275                 Notification notification = mock(Notification.class);
276                 when(notification.getId()).thenReturn("random-notification");
277                 List<Notification> notifications = Arrays.asList(notification);
278                 List<Notification> filteredNotifications = listNotificationFilter.filterNotifications(notifications, null);
279                 assertThat(filteredNotifications, contains(notification));
280         }
281
282 }