1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.notifications.filters.internal.scope

File ScopeNotificationFilterTest.java

 

Code metrics

8
114
8
1
352
245
12
0.11
14.25
8
1.5

Classes

Class Line # Actions
ScopeNotificationFilterTest 71 114 0% 12 0
1.0100%
 

Contributing tests

This file is covered by 6 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.notifications.filters.internal.scope;
21   
22    import java.util.Arrays;
23    import java.util.Collection;
24    import java.util.Collections;
25    import java.util.Date;
26    import java.util.HashMap;
27    import java.util.List;
28    import java.util.Map;
29   
30    import org.junit.Before;
31    import org.junit.Rule;
32    import org.junit.Test;
33    import org.mockito.internal.util.collections.Sets;
34    import org.xwiki.eventstream.Event;
35    import org.xwiki.model.EntityType;
36    import org.xwiki.model.reference.DocumentReference;
37    import org.xwiki.model.reference.EntityReference;
38    import org.xwiki.model.reference.EntityReferenceResolver;
39    import org.xwiki.model.reference.EntityReferenceSerializer;
40    import org.xwiki.model.reference.SpaceReference;
41    import org.xwiki.model.reference.WikiReference;
42    import org.xwiki.notifications.NotificationFormat;
43    import org.xwiki.notifications.filters.NotificationFilter;
44    import org.xwiki.notifications.filters.NotificationFilterManager;
45    import org.xwiki.notifications.filters.NotificationFilterPreference;
46    import org.xwiki.notifications.filters.NotificationFilterType;
47    import org.xwiki.notifications.filters.internal.LocationOperatorNodeGenerator;
48    import org.xwiki.notifications.preferences.NotificationPreference;
49    import org.xwiki.notifications.preferences.NotificationPreferenceCategory;
50    import org.xwiki.notifications.preferences.NotificationPreferenceProperty;
51    import org.xwiki.test.annotation.ComponentList;
52    import org.xwiki.test.mockito.MockitoComponentMockingRule;
53   
54    import static org.junit.Assert.assertEquals;
55    import static org.junit.Assert.assertFalse;
56    import static org.junit.Assert.assertNull;
57    import static org.junit.Assert.assertTrue;
58    import static org.mockito.ArgumentMatchers.eq;
59    import static org.mockito.Mockito.mock;
60    import static org.mockito.Mockito.when;
61   
62    /**
63    * @version $Id: 0bcd4888ce4137a6a59d2d387472f40e096bec73 $
64    */
65    @ComponentList({
66    LocationOperatorNodeGenerator.class,
67    ScopeNotificationFilterExpressionGenerator.class,
68    ScopeNotificationFilterPreferencesGetter.class,
69    ScopeNotificationFilterLocationStateComputer.class
70    })
 
71    public class ScopeNotificationFilterTest
72    {
73    @Rule
74    public final MockitoComponentMockingRule<ScopeNotificationFilter> mocker =
75    new MockitoComponentMockingRule<>(ScopeNotificationFilter.class);
76   
77    private NotificationFilterManager notificationFilterManager;
78    private EntityReferenceSerializer<String> serializer;
79    private EntityReferenceSerializer<String> globalSerializer;
80    private EntityReferenceResolver<String> resolver;
81   
 
82  6 toggle @Before
83    public void setUp() throws Exception
84    {
85  6 notificationFilterManager = mock(NotificationFilterManager.class);
86  6 mocker.registerComponent(NotificationFilterManager.class, notificationFilterManager);
87  6 serializer = mock(EntityReferenceSerializer.class);
88  6 mocker.registerComponent(EntityReferenceSerializer.TYPE_STRING, "local", serializer);
89  6 globalSerializer = mock(EntityReferenceSerializer.class);
90  6 mocker.registerComponent(EntityReferenceSerializer.TYPE_STRING, globalSerializer);
91  6 resolver = mock(EntityReferenceResolver.class);
92  6 mocker.registerComponent(EntityReferenceResolver.TYPE_STRING, resolver);
93    }
94   
 
95  8 toggle private NotificationFilterPreference mockNotificationFilterPreference(String entityStringValue,
96    EntityReference resultReference, NotificationFilterType filterType, String eventName)
97    {
98  8 NotificationFilterPreference preference = mock(NotificationFilterPreference.class);
99  8 if (resultReference.getType() == EntityType.SPACE) {
100  4 when(preference.getPage()).thenReturn(entityStringValue);
101    }
102  8 if (resultReference.getType() == EntityType.DOCUMENT) {
103  3 when(preference.getPageOnly()).thenReturn(entityStringValue);
104    }
105  8 if (resultReference.getType() == EntityType.WIKI) {
106  1 when(preference.getWiki()).thenReturn(entityStringValue);
107    }
108  8 when(preference.getFilterName()).thenReturn(ScopeNotificationFilter.FILTER_NAME);
109  8 if (eventName != null) {
110  1 when(preference.getEventTypes()).thenReturn(Sets.newSet(eventName));
111    }
112  8 when(preference.getFilterType()).thenReturn(filterType);
113  8 when(preference.getNotificationFormats()).thenReturn(
114    Sets.newSet(NotificationFormat.ALERT, NotificationFormat.EMAIL));
115  8 when(preference.isEnabled()).thenReturn(true);
116   
117  8 when(resolver.resolve(entityStringValue, resultReference.getType())).thenReturn(resultReference);
118   
119  8 when(serializer.serialize(eq(resultReference))).thenReturn(entityStringValue);
120   
121  8 when(preference.getProviderHint()).thenReturn("userProfile");
122   
123  8 return preference;
124    }
125   
 
126  1 toggle @Test
127    public void matchPreferenceWithCorrectPreference() throws Exception
128    {
129  1 NotificationPreference preference = mock(NotificationPreference.class);
130  1 when(preference.getCategory()).thenReturn(NotificationPreferenceCategory.DEFAULT);
131  1 when(preference.getProperties()).thenReturn(
132    Collections.singletonMap(NotificationPreferenceProperty.EVENT_TYPE, ""));
133   
134  1 assertTrue(mocker.getComponentUnderTest().matchesPreference(preference));
135    }
136   
 
137  1 toggle @Test
138    public void matchPreferenceWithIncorrectPreference() throws Exception
139    {
140  1 NotificationPreference preference = mock(NotificationPreference.class);
141  1 when(preference.getCategory()).thenReturn(NotificationPreferenceCategory.SYSTEM);
142   
143  1 assertFalse(mocker.getComponentUnderTest().matchesPreference(preference));
144    }
145   
 
146  1 toggle @Test
147    public void getName() throws Exception
148    {
149  1 assertEquals(ScopeNotificationFilter.FILTER_NAME, mocker.getComponentUnderTest().getName());
150    }
151   
 
152  1 toggle @Test
153    public void complexCase1() throws Exception
154    {
155    // Preferences:
156    //
157    // α: "update" event type enabled for format ALERT
158    //
159    // β: Exclusive filter on "wikiA".
160    // γ: Inclusive filter on "wikiA:SpaceB"
161    // δ: Exclusive filter on "wikiA:SpaceB.SpaceC"
162    // ε: Exclusive filter on "wikiA:SpaceB.SpaceC.SpaceD"
163   
164    // Mock α
165  1 NotificationPreference preference = mock(NotificationPreference.class);
166  1 when(preference.getFormat()).thenReturn(NotificationFormat.ALERT);
167  1 Map<NotificationPreferenceProperty, Object> properties = new HashMap<>();
168  1 properties.put(NotificationPreferenceProperty.EVENT_TYPE, "update");
169  1 when(preference.getProperties()).thenReturn(properties);
170   
171    // Mock β
172  1 WikiReference wikiReference = new WikiReference("wikiA");
173  1 NotificationFilterPreference prefβ = mockNotificationFilterPreference("wikiA",
174    wikiReference, NotificationFilterType.EXCLUSIVE, null);
175   
176    // Mock γ
177  1 SpaceReference spaceReferenceB = new SpaceReference("SpaceB", wikiReference);
178  1 NotificationFilterPreference prefγ = mockNotificationFilterPreference("wikiA:SpaceB",
179    spaceReferenceB, NotificationFilterType.INCLUSIVE, "update");
180   
181    // Mock δ
182  1 SpaceReference spaceReferenceC = new SpaceReference("SpaceC", spaceReferenceB);
183  1 NotificationFilterPreference prefδ = mockNotificationFilterPreference("wikiA:SpaceB.SpaceC",
184    spaceReferenceC, NotificationFilterType.EXCLUSIVE, null);
185   
186    // Mock ε
187  1 SpaceReference spaceReferenceD = new SpaceReference("SpaceD", spaceReferenceC);
188  1 NotificationFilterPreference prefε = mockNotificationFilterPreference("wikiA:SpaceB.SpaceC.SpaceD",
189    spaceReferenceD, NotificationFilterType.INCLUSIVE, null);
190   
191  1 Collection<NotificationFilterPreference> filterPreferences = Sets.newSet(prefβ, prefγ, prefδ, prefε);
192   
193  1 DocumentReference user = new DocumentReference("xwiki", "XWiki", "User");
194   
195    // Test 1
196  1 String result = mocker.getComponentUnderTest().filterExpression(user, filterPreferences, preference).toString();
197  1 assertEquals("(((NOT (WIKI = \"wikiA\") OR (WIKI = \"wikiA\" AND SPACE STARTS WITH \"wikiA:SpaceB\")) " +
198    "OR (WIKI = \"wikiA\" AND SPACE STARTS WITH \"wikiA:SpaceB.SpaceC.SpaceD\")) AND (NOT ((WIKI = \"wikiA\" " +
199    "AND SPACE STARTS WITH \"wikiA:SpaceB.SpaceC\")) OR (WIKI = \"wikiA\" " +
200    "AND SPACE STARTS WITH \"wikiA:SpaceB.SpaceC.SpaceD\")))", result);
201   
202    // Test with wikiA:SpaceE (filtered by β)
203  1 Event event1 = mock(Event.class);
204  1 when(event1.getSpace()).thenReturn(new SpaceReference("SpaceE", wikiReference));
205  1 assertEquals(NotificationFilter.FilterPolicy.FILTER,
206    mocker.getComponentUnderTest().filterEvent(event1, user, filterPreferences, NotificationFormat.ALERT));
207   
208    // Test with wikiA:SpaceB.DocumentE (kept by γ)
209  1 Event event2 = mock(Event.class);
210  1 when(event2.getDocument()).thenReturn(new DocumentReference("DocumentE", spaceReferenceB));
211  1 assertEquals(NotificationFilter.FilterPolicy.NO_EFFECT,
212    mocker.getComponentUnderTest().filterEvent(event2, user, filterPreferences, NotificationFormat.ALERT));
213   
214    // Test with wikiA:SpaceB.SpaceC.DocumentF (filtered by δ)
215  1 Event event3 = mock(Event.class);
216  1 when(event3.getDocument()).thenReturn(new DocumentReference("DocumentF", spaceReferenceC));
217  1 assertEquals(NotificationFilter.FilterPolicy.FILTER,
218    mocker.getComponentUnderTest().filterEvent(event3, user, filterPreferences, NotificationFormat.ALERT));
219   
220    // Test with wikiA:SpaceB.SpaceC.SpaceD.DocumentG (kept by ε)
221  1 Event event4 = mock(Event.class);
222  1 when(event4.getDocument()).thenReturn(new DocumentReference("DocumentG", spaceReferenceD));
223  1 assertEquals(NotificationFilter.FilterPolicy.NO_EFFECT,
224    mocker.getComponentUnderTest().filterEvent(event4, user, filterPreferences, NotificationFormat.ALERT));
225   
226    // Test with wikiB:SpaceH.DocumentI - kept because nothing match and there is no top level inclusive filter
227  1 Event event5 = mock(Event.class);
228  1 when(event5.getDocument()).thenReturn(new DocumentReference("wikiB", "SpaceH", "DocumentI"));
229  1 assertEquals(NotificationFilter.FilterPolicy.NO_EFFECT,
230    mocker.getComponentUnderTest().filterEvent(event5, user, filterPreferences, NotificationFormat.ALERT));
231    }
232   
 
233  1 toggle @Test
234    public void testWithTopLevelInclusiveFilters() throws Exception
235    {
236    // Preferences:
237    //
238    // α: "update" event type enabled for format ALERT
239    //
240    // γ: Inclusive filter on "wikiA:SpaceB"
241    // ζ: Inclusive filter on "wikiA:SpaceM.DocumentN"
242   
243    // Mock α
244  1 NotificationPreference preference = mock(NotificationPreference.class);
245  1 when(preference.getFormat()).thenReturn(NotificationFormat.ALERT);
246  1 Map<NotificationPreferenceProperty, Object> properties = new HashMap<>();
247  1 properties.put(NotificationPreferenceProperty.EVENT_TYPE, "update");
248  1 when(preference.getProperties()).thenReturn(properties);
249   
250    // Mock γ
251  1 WikiReference wikiReference = new WikiReference("wikiA");
252  1 SpaceReference spaceReferenceB = new SpaceReference("SpaceB", new WikiReference(wikiReference));
253  1 NotificationFilterPreference prefγ = mockNotificationFilterPreference("wikiA:SpaceB",
254    spaceReferenceB, NotificationFilterType.INCLUSIVE, null);
255   
256    // Mock ζ
257  1 DocumentReference documentReference = new DocumentReference("wikiA", "SpaceM", "DocumentN");
258  1 NotificationFilterPreference prefζ = mockNotificationFilterPreference("wikiA:SpaceM.DocumentN",
259    documentReference, NotificationFilterType.INCLUSIVE, null);
260  1 when(prefζ.getProviderHint()).thenReturn("userProfile");
261   
262  1 Collection<NotificationFilterPreference> filterPreferences = Sets.newSet(prefγ, prefζ);
263   
264  1 DocumentReference user = new DocumentReference("xwiki", "XWiki", "User");
265   
266    // Test 1
267  1 String result = mocker.getComponentUnderTest().filterExpression(user, filterPreferences, preference).toString();
268  1 assertEquals("(WIKI = \"wikiA\" AND SPACE STARTS WITH \"wikiA:SpaceB\")", result);
269   
270    // Test with wikiA:SpaceE (filtered by γ & ζ)
271  1 Event event1 = mock(Event.class);
272  1 when(event1.getSpace()).thenReturn(new SpaceReference("SpaceE", wikiReference));
273  1 assertEquals(NotificationFilter.FilterPolicy.FILTER,
274    mocker.getComponentUnderTest().filterEvent(event1, user, filterPreferences, NotificationFormat.ALERT));
275   
276    // Test with wikiA:SpaceB.DocumentJ (kept by γ)
277  1 Event event2 = mock(Event.class);
278  1 when(event2.getDocument()).thenReturn(new DocumentReference("wikiA", "SpaceB", "DocumentJ"));
279  1 assertEquals(NotificationFilter.FilterPolicy.NO_EFFECT,
280    mocker.getComponentUnderTest().filterEvent(event2, user, filterPreferences, NotificationFormat.ALERT));
281   
282    // Test with wikiB:SpaceK.DocumentL (filtered by γ & ζ)
283  1 Event event3 = mock(Event.class);
284  1 when(event3.getDocument()).thenReturn(new DocumentReference("wikiB", "SpaceK", "DocumentL"));
285  1 assertEquals(NotificationFilter.FilterPolicy.FILTER,
286    mocker.getComponentUnderTest().filterEvent(event3, user, filterPreferences, NotificationFormat.ALERT));
287   
288    // Test with wikiA:SpaceM.DocumentN (kept by ζ)
289  1 Event event4 = mock(Event.class);
290  1 when(event4.getDocument()).thenReturn(new DocumentReference("wikiA", "SpaceM", "DocumentN"));
291  1 assertEquals(NotificationFilter.FilterPolicy.NO_EFFECT,
292    mocker.getComponentUnderTest().filterEvent(event4, user, filterPreferences, NotificationFormat.ALERT));
293    }
294   
 
295  1 toggle @Test
296    public void testFilterExpressionWithSubQuery() throws Exception
297    {
298  1 NotificationPreference pref1 = mock(NotificationPreference.class);
299  1 NotificationPreference pref2 = mock(NotificationPreference.class);
300  1 Map<NotificationPreferenceProperty, Object> properties1 = new HashMap<>();
301  1 Map<NotificationPreferenceProperty, Object> properties2 = new HashMap<>();
302  1 when(pref1.getProperties()).thenReturn(properties1);
303  1 when(pref2.getProperties()).thenReturn(properties2);
304  1 properties1.put(NotificationPreferenceProperty.EVENT_TYPE, "type1");
305  1 properties2.put(NotificationPreferenceProperty.EVENT_TYPE, "type2");
306  1 when(pref1.isNotificationEnabled()).thenReturn(true);
307  1 when(pref2.isNotificationEnabled()).thenReturn(true);
308  1 when(pref1.getStartDate()).thenReturn(new Date(0));
309  1 when(pref2.getStartDate()).thenReturn(new Date(100000L));
310   
311  1 List<NotificationPreference> notificationFilterPreferences = Arrays.asList(pref1, pref2);
312   
313  1 DocumentReference pageRef = new DocumentReference("wikiA", "SpaceB", "PageC");
314  1 NotificationFilterPreference prefγ = mockNotificationFilterPreference("wikiA:SpaceB:PageC",
315    pageRef, NotificationFilterType.INCLUSIVE, null);
316  1 NotificationFilterPreference prefz = mockNotificationFilterPreference("wikiA:SpaceB:PageD",
317    pageRef, NotificationFilterType.EXCLUSIVE, null);
318   
319  1 Collection<NotificationFilterPreference> filterPreferences = Sets.newSet(prefγ);
320   
321  1 DocumentReference user = new DocumentReference("xwiki", "XWiki", "User");
322   
323    // Test 1
324  1 assertEquals(
325    "(((TYPE = \"type1\" AND DATE >= \"" + new Date(0).toString() + "\") " +
326    "OR (TYPE = \"type2\" AND DATE >= \"" + new Date(100000L).toString() + "\")) " +
327    "AND CONCAT(CONCAT(WIKI, \":\"), PAGE) IN " +
328    "(SELECT nfp.pageOnly FROM DefaultNotificationFilterPreference nfp WHERE nfp.owner = :owner " +
329    "AND nfp.filterType = 0 AND nfp.filterName = 'scopeNotificationFilter' " +
330    "AND nfp.pageOnly IS NOT NULL AND nfp.pageOnly <> '' " +
331    "AND (nfp.allEventTypes = '' OR nfp.allEventTypes IS NULL) " +
332    "AND nfp.alertEnabled = true AND nfp.enabled = true))",
333    mocker.getComponentUnderTest().filterExpression(user, filterPreferences, NotificationFilterType.INCLUSIVE,
334    NotificationFormat.ALERT, notificationFilterPreferences).toString());
335   
336    // Test 2
337  1 assertNull(mocker.getComponentUnderTest().filterExpression(user, filterPreferences, NotificationFilterType.EXCLUSIVE,
338    NotificationFormat.ALERT, notificationFilterPreferences));
339   
340    // Test 3
341  1 filterPreferences = Sets.newSet(prefγ, prefz);
342  1 assertEquals(
343    "NOT (CONCAT(CONCAT(WIKI, \":\"), PAGE) IN (SELECT nfp.pageOnly " +
344    "FROM DefaultNotificationFilterPreference nfp " +
345    "WHERE nfp.owner = :owner AND nfp.filterType = 1 AND nfp.filterName = 'scopeNotificationFilter' " +
346    "AND nfp.pageOnly IS NOT NULL AND nfp.pageOnly <> '' " +
347    "AND (nfp.allEventTypes = '' OR nfp.allEventTypes IS NULL) " +
348    "AND nfp.emailEnabled = true AND nfp.enabled = true))",
349    mocker.getComponentUnderTest().filterExpression(user, filterPreferences, NotificationFilterType.EXCLUSIVE,
350    NotificationFormat.EMAIL, notificationFilterPreferences).toString());
351    }
352    }