1 package com.atlassian.streams.refapp;
2
3
4 import com.atlassian.sal.api.ApplicationProperties;
5 import com.atlassian.streams.api.ActivityRequest;
6 import com.atlassian.streams.api.ActivityVerb;
7 import com.atlassian.streams.api.StreamsEntry;
8 import com.atlassian.streams.api.StreamsFilterType;
9 import com.atlassian.streams.api.common.Pair;
10 import com.atlassian.streams.refapp.api.StreamsEntryRequest;
11 import com.atlassian.streams.spi.StreamsI18nResolver;
12 import com.google.common.base.Function;
13 import com.google.common.base.Predicate;
14 import com.google.common.collect.ImmutableList;
15 import com.google.common.collect.ImmutableMultimap;
16 import com.google.common.collect.Iterables;
17 import com.google.common.collect.Multimap;
18 import org.joda.time.DateTime;
19 import org.junit.Before;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22 import org.mockito.Mock;
23 import org.mockito.runners.MockitoJUnitRunner;
24
25 import javax.annotation.Nullable;
26 import java.util.Arrays;
27
28 import static com.atlassian.streams.api.ActivityObjectTypes.article;
29 import static com.atlassian.streams.api.ActivityVerbs.like;
30 import static com.atlassian.streams.api.ActivityVerbs.post;
31 import static com.atlassian.streams.api.StreamsFilterType.Operator.AFTER;
32 import static com.atlassian.streams.api.StreamsFilterType.Operator.BEFORE;
33 import static com.atlassian.streams.api.StreamsFilterType.Operator.BETWEEN;
34 import static com.atlassian.streams.api.StreamsFilterType.Operator.IS;
35 import static com.atlassian.streams.api.StreamsFilterType.Operator.NOT;
36 import static com.atlassian.streams.api.common.Pair.pair;
37 import static com.atlassian.streams.refapp.RefappStreamsActivityManager.BUFFER_SIZE;
38 import static com.atlassian.streams.spi.StandardStreamsFilterOption.ACTIVITY_KEY;
39 import static com.atlassian.streams.spi.StandardStreamsFilterOption.UPDATE_DATE;
40 import static com.atlassian.streams.spi.StandardStreamsFilterOption.USER;
41 import static com.google.common.collect.Iterables.size;
42 import static org.hamcrest.MatcherAssert.assertThat;
43 import static org.hamcrest.Matchers.is;
44 import static org.hamcrest.Matchers.notNullValue;
45 import static org.hamcrest.Matchers.nullValue;
46 import static org.mockito.Mockito.mock;
47 import static org.mockito.Mockito.when;
48
49 @RunWith(MockitoJUnitRunner.class)
50 public class RefappStreamsActivityManagerTest {
51 private static final ImmutableMultimap<String, Pair<StreamsFilterType.Operator, Iterable<String>>> EMPTY_FILTER = ImmutableMultimap.<String, Pair<StreamsFilterType.Operator, Iterable<String>>>builder().build();
52 private RefappStreamsActivityManager refappStreamsActivityManager;
53
54 @Mock
55 private ApplicationProperties applicationProperties;
56 @Mock
57 private StreamsI18nResolver i18nResolver;
58 @Mock
59 private RefappRenderer refappRenderer;
60
61 private DateTime today;
62
63 @Before
64 public void setup() {
65 refappStreamsActivityManager = new RefappStreamsActivityManager(applicationProperties, i18nResolver, refappRenderer);
66 today = new DateTime();
67
68
69
70 for (int i = 0; i < BUFFER_SIZE; i++) {
71 final ActivityVerb verb = i < 5 ? post() : like();
72 refappStreamsActivityManager.addEntry(new StreamsEntryRequest()
73 .id(i)
74 .title("Title " + i)
75 .postedDate(today.plusDays(i))
76 .type(article())
77 .verb(verb)
78 .user("User" + i));
79 }
80
81 }
82
83 @Test
84 public void getEntriesTestNoFilter() {
85
86 getEntriesNoFilterAndAssert(5, 5);
87
88
89 getEntriesNoFilterAndAssert(BUFFER_SIZE, BUFFER_SIZE);
90 }
91
92 @Test
93 public void getEntriesTestFilterDateDefore() {
94
95 Pair<StreamsFilterType.Operator, Iterable<String>> dateFilter = pairDateFilter(BEFORE, today.plusDays(2));
96 Iterable<StreamsEntry> entries = getStreamsEntriesWithDateFilter(dateFilter);
97
98 assertThat(size(entries), is(2));
99
100 assertThat(find(entries, 0), notNullValue());
101 assertThat(find(entries, 1), notNullValue());
102 }
103
104 @Test
105 public void getEntriesTestFilterDateAfter() {
106
107 Pair<StreamsFilterType.Operator, Iterable<String>> dateFilter = pairDateFilter(AFTER, today.plusDays(2));
108 Iterable<StreamsEntry> entries = getStreamsEntriesWithDateFilter(dateFilter);
109
110 assertThat(size(entries), is(BUFFER_SIZE - 3));
111
112 assertThat(find(entries, 2), nullValue());
113 assertThat(find(entries, 3), notNullValue());
114 assertThat(find(entries, BUFFER_SIZE - 1), notNullValue());
115 }
116
117 private Pair<StreamsFilterType.Operator, Iterable<String>> pairDateFilter(final StreamsFilterType.Operator operator, final DateTime... dates) {
118 Iterable<String> dateStrings = Iterables.<DateTime, String>transform(Arrays.asList(dates), new Function<DateTime, String>() {
119 @Override
120 public String apply(@Nullable final DateTime input) {
121 return String.valueOf(input.toDate().getTime());
122 }
123 });
124 return Pair.<StreamsFilterType.Operator, Iterable<String>>pair(operator, dateStrings);
125 }
126
127 @Test
128 public void getEntriesTestFilterDateBetween() {
129
130 Pair<StreamsFilterType.Operator, Iterable<String>> dateFilter = pairDateFilter(BETWEEN, today.plusDays(2), today.plusDays(5));
131 Iterable<StreamsEntry> entries = getStreamsEntriesWithDateFilter(dateFilter);
132
133 assertThat(size(entries), is(2));
134 assertThat(find(entries, 3), notNullValue());
135 assertThat(find(entries, 4), notNullValue());
136 }
137
138 @Test
139 public void getEntriesTestFilterUserIs() {
140 Iterable<String> users = ImmutableList.of("User6");
141 Pair<StreamsFilterType.Operator, Iterable<String>> dateFilter = pair(IS, users);
142 Iterable<StreamsEntry> entries = getStreamsEntriesWithUserFilter(dateFilter);
143
144 assertThat(size(entries), is(1));
145 assertThat(find(entries, 6), notNullValue());
146 }
147
148 @Test
149 public void getEntriesTestFilterUserIsNot() {
150 Iterable<String> users = ImmutableList.of("User6");
151 Pair<StreamsFilterType.Operator, Iterable<String>> dateFilter = pair(NOT, users);
152 Iterable<StreamsEntry> entries = getStreamsEntriesWithUserFilter(dateFilter);
153
154 assertThat(size(entries), is(BUFFER_SIZE - 1));
155 assertThat(find(entries, 6), nullValue());
156 }
157
158 @Test
159 public void getEntriesTestFilterActivity() {
160
161 Iterable<StreamsEntry> entries = getStreamsEntriesWithActivityFilter("article:post");
162 assertThat(size(entries), is(5));
163
164
165 entries = getStreamsEntriesWithActivityFilter("article:like");
166 assertThat(size(entries), is(BUFFER_SIZE - 5));
167 }
168
169 @Test
170 public void addEntryTest() {
171
172 StreamsEntryRequest entryRequest = new StreamsEntryRequest()
173 .id(BUFFER_SIZE)
174 .postedDate(new DateTime().plusDays(BUFFER_SIZE))
175 .title("Title" + BUFFER_SIZE)
176 .user("User" + BUFFER_SIZE)
177 .type(article())
178 .verb(post());
179 refappStreamsActivityManager.addEntry(entryRequest);
180
181
182 assertThat(refappStreamsActivityManager.getEntry(0), nullValue());
183
184
185 StreamsEntry entry = refappStreamsActivityManager.getEntry(entryRequest.getId());
186 assertThat(entry, notNullValue());
187 assertThat(entry.getPostedDate(), is(entryRequest.getPostedDate()));
188 assertThat(entry.getVerb(), is(entryRequest.getVerb()));
189 assertThat(entry.getActivityObjects().iterator().next().getActivityObjectType().get(), is(entryRequest.getType()));
190 assertThat(entry.getAuthors().iterator().next().getUsername(), is(entryRequest.getUser()));
191 }
192
193 @Test
194 public void removeEntryTest() {
195 removeEntryAndAssert(5);
196
197 getEntriesNoFilterAndAssert(BUFFER_SIZE, BUFFER_SIZE - 1);
198
199 removeEntryAndAssert(6);
200
201 getEntriesNoFilterAndAssert(BUFFER_SIZE, BUFFER_SIZE - 2);
202 }
203
204 private void removeEntryAndAssert(final int removedId) {
205 assertThat(refappStreamsActivityManager.getEntry(removedId), notNullValue());
206 assertThat(refappStreamsActivityManager.removeEntry(removedId), is(true));
207 assertThat(refappStreamsActivityManager.getEntry(removedId), nullValue());
208 assertThat(refappStreamsActivityManager.removeEntry(removedId), is(false));
209 }
210
211 private Iterable<StreamsEntry> getStreamsEntriesWithUserFilter(final Pair<StreamsFilterType.Operator, Iterable<String>> dateFilter) {
212 ImmutableMultimap<String, Pair<StreamsFilterType.Operator, Iterable<String>>> standardFilters = ImmutableMultimap.<String, Pair<StreamsFilterType.Operator, Iterable<String>>>builder()
213 .put(USER.getKey(), dateFilter).build();
214
215 ActivityRequest request = mockActivityRequest(BUFFER_SIZE, standardFilters, EMPTY_FILTER);
216
217 return refappStreamsActivityManager.getEntries(request);
218 }
219
220 private Iterable<StreamsEntry> getStreamsEntriesWithDateFilter(final Pair<StreamsFilterType.Operator, Iterable<String>> dateFilter) {
221 ImmutableMultimap<String, Pair<StreamsFilterType.Operator, Iterable<String>>> standardFilters = ImmutableMultimap.<String, Pair<StreamsFilterType.Operator, Iterable<String>>>builder()
222 .put(UPDATE_DATE.getKey(), dateFilter).build();
223
224 ActivityRequest request = mockActivityRequest(BUFFER_SIZE, standardFilters, EMPTY_FILTER);
225
226 return refappStreamsActivityManager.getEntries(request);
227 }
228
229 public StreamsEntry find(Iterable<StreamsEntry> entries, final int id) {
230 return (StreamsEntry) Iterables.find(entries, new Predicate<StreamsEntry>() {
231 @Override
232 public boolean apply(@Nullable final StreamsEntry input) {
233 return input.getId().equals(refappStreamsActivityManager.buildUriId(id));
234 }
235 }, null);
236 }
237
238 private ActivityRequest mockActivityRequest(final int maxResult,
239 final Multimap<String, Pair<StreamsFilterType.Operator, Iterable<String>>> standardFilters,
240 final Multimap<String, Pair<StreamsFilterType.Operator, Iterable<String>>> providerFilters) {
241 ActivityRequest request = mock(ActivityRequest.class);
242 when(request.getMaxResults()).thenReturn(maxResult);
243
244 when(request.getStandardFilters()).thenReturn(standardFilters);
245 when(request.getProviderFilters()).thenReturn(providerFilters);
246 return request;
247 }
248
249 private void getEntriesNoFilterAndAssert(final int maxResult, final int expectedResult) {
250
251 ActivityRequest request = mockActivityRequest(maxResult, EMPTY_FILTER, EMPTY_FILTER);
252
253 Iterable<StreamsEntry> entries = refappStreamsActivityManager.getEntries(request);
254 assertThat(size(entries), is(expectedResult));
255 }
256
257
258 private Iterable<StreamsEntry> getStreamsEntriesWithActivityFilter(final String activity) {
259 Iterable<String> activities = ImmutableList.of(activity);
260 Pair<StreamsFilterType.Operator, Iterable<String>> activityFilter = pair(IS, activities);
261 ImmutableMultimap<String, Pair<StreamsFilterType.Operator, Iterable<String>>> providerFilter = ImmutableMultimap.<String, Pair<StreamsFilterType.Operator, Iterable<String>>>builder()
262 .put(ACTIVITY_KEY, activityFilter).build();
263
264 ActivityRequest request = mockActivityRequest(BUFFER_SIZE, EMPTY_FILTER, providerFilter);
265
266 return refappStreamsActivityManager.getEntries(request);
267 }
268
269 }