Search in sources :

Example 11 with NotificationPreference

use of org.xwiki.notifications.preferences.NotificationPreference in project xwiki-platform by xwiki.

the class ScopeNotificationFilterTest method complexCase1.

@Test
public void complexCase1() throws Exception {
    // Preferences:
    // 
    // α: "update" event type enabled for format ALERT
    // 
    // β: Exclusive filter on "wikiA".
    // γ: Inclusive filter on "wikiA:SpaceB"
    // δ: Exclusive filter on "wikiA:SpaceB.SpaceC"
    // ε: Exclusive filter on "wikiA:SpaceB.SpaceC.SpaceD"
    // Mock α
    NotificationPreference preference = mock(NotificationPreference.class);
    when(preference.getFormat()).thenReturn(NotificationFormat.ALERT);
    Map<NotificationPreferenceProperty, Object> properties = new HashMap<>();
    properties.put(NotificationPreferenceProperty.EVENT_TYPE, "update");
    when(preference.getProperties()).thenReturn(properties);
    // Mock β
    WikiReference wikiReference = new WikiReference("wikiA");
    NotificationFilterPreference prefβ = mockNotificationFilterPreference("wikiA", wikiReference, NotificationFilterType.EXCLUSIVE, null);
    // Mock γ
    SpaceReference spaceReferenceB = new SpaceReference("SpaceB", wikiReference);
    NotificationFilterPreference prefγ = mockNotificationFilterPreference("wikiA:SpaceB", spaceReferenceB, NotificationFilterType.INCLUSIVE, "update");
    // Mock δ
    SpaceReference spaceReferenceC = new SpaceReference("SpaceC", spaceReferenceB);
    NotificationFilterPreference prefδ = mockNotificationFilterPreference("wikiA:SpaceB.SpaceC", spaceReferenceC, NotificationFilterType.EXCLUSIVE, null);
    // Mock ε
    SpaceReference spaceReferenceD = new SpaceReference("SpaceD", spaceReferenceC);
    NotificationFilterPreference prefε = mockNotificationFilterPreference("wikiA:SpaceB.SpaceC.SpaceD", spaceReferenceD, NotificationFilterType.INCLUSIVE, null);
    when(notificationFilterManager.getFilterPreferences(any(DocumentReference.class))).thenReturn(Sets.newSet(prefβ, prefγ, prefδ, prefε));
    DocumentReference user = new DocumentReference("xwiki", "XWiki", "User");
    // Test 1
    String result = mocker.getComponentUnderTest().filterExpression(user, preference).toString();
    assertEquals("(((NOT (WIKI = \"wikiA\") OR (WIKI = \"wikiA\" AND SPACE STARTS WITH \"wikiA:SpaceB\"))" + " OR (WIKI = \"wikiA\" AND SPACE STARTS WITH \"wikiA:SpaceB.SpaceC.SpaceD\")) AND (NOT ((WIKI = \"wikiA\" " + "AND SPACE STARTS WITH \"wikiA:SpaceB.SpaceC\")) OR (WIKI = \"wikiA\" " + "AND SPACE STARTS WITH \"wikiA:SpaceB.SpaceC.SpaceD\")))", result);
    // Test with wikiA:SpaceE (filtered by β)
    Event event1 = mock(Event.class);
    when(event1.getSpace()).thenReturn(new SpaceReference("SpaceE", wikiReference));
    assertEquals(NotificationFilter.FilterPolicy.FILTER, mocker.getComponentUnderTest().filterEvent(event1, user, NotificationFormat.ALERT));
    // Test with wikiA:SpaceB.DocumentE (kept by γ)
    Event event2 = mock(Event.class);
    when(event2.getDocument()).thenReturn(new DocumentReference("DocumentE", spaceReferenceB));
    assertEquals(NotificationFilter.FilterPolicy.NO_EFFECT, mocker.getComponentUnderTest().filterEvent(event2, user, NotificationFormat.ALERT));
    // Test with wikiA:SpaceB.SpaceC.DocumentF (filtered by δ)
    Event event3 = mock(Event.class);
    when(event3.getDocument()).thenReturn(new DocumentReference("DocumentF", spaceReferenceC));
    assertEquals(NotificationFilter.FilterPolicy.FILTER, mocker.getComponentUnderTest().filterEvent(event3, user, NotificationFormat.ALERT));
    // Test with wikiA:SpaceB.SpaceC.SpaceD.DocumentG (kept by ε)
    Event event4 = mock(Event.class);
    when(event4.getDocument()).thenReturn(new DocumentReference("DocumentG", spaceReferenceD));
    assertEquals(NotificationFilter.FilterPolicy.NO_EFFECT, mocker.getComponentUnderTest().filterEvent(event4, user, NotificationFormat.ALERT));
    // Test with wikiB:SpaceH.DocumentI - kept because nothing match and there is no top level inclusive filter
    Event event5 = mock(Event.class);
    when(event5.getDocument()).thenReturn(new DocumentReference("wikiB", "SpaceH", "DocumentI"));
    assertEquals(NotificationFilter.FilterPolicy.NO_EFFECT, mocker.getComponentUnderTest().filterEvent(event5, user, NotificationFormat.ALERT));
}
Also used : NotificationPreference(org.xwiki.notifications.preferences.NotificationPreference) HashMap(java.util.HashMap) SpaceReference(org.xwiki.model.reference.SpaceReference) NotificationFilterPreference(org.xwiki.notifications.filters.NotificationFilterPreference) NotificationPreferenceProperty(org.xwiki.notifications.preferences.NotificationPreferenceProperty) Event(org.xwiki.eventstream.Event) WikiReference(org.xwiki.model.reference.WikiReference) DocumentReference(org.xwiki.model.reference.DocumentReference) Test(org.junit.Test)

Example 12 with NotificationPreference

use of org.xwiki.notifications.preferences.NotificationPreference in project xwiki-platform by xwiki.

the class ScopeNotificationFilterTest method testWithTopLevelInclusiveFilters.

@Test
public void testWithTopLevelInclusiveFilters() throws Exception {
    // Preferences:
    // 
    // α: "update" event type enabled for format ALERT
    // 
    // γ: Inclusive filter on "wikiA:SpaceB"
    // ζ: Inclusive filter on "wikiA:SpaceM.DocumentN"
    // Mock α
    NotificationPreference preference = mock(NotificationPreference.class);
    when(preference.getFormat()).thenReturn(NotificationFormat.ALERT);
    Map<NotificationPreferenceProperty, Object> properties = new HashMap<>();
    properties.put(NotificationPreferenceProperty.EVENT_TYPE, "update");
    when(preference.getProperties()).thenReturn(properties);
    // Mock γ
    WikiReference wikiReference = new WikiReference("wikiA");
    SpaceReference spaceReferenceB = new SpaceReference("SpaceB", new WikiReference(wikiReference));
    NotificationFilterPreference prefγ = mockNotificationFilterPreference("wikiA:SpaceB", spaceReferenceB, NotificationFilterType.INCLUSIVE, null);
    // Mock ζ
    DocumentReference documentReference = new DocumentReference("wikiA", "SpaceM", "DocumentN");
    NotificationFilterPreference prefζ = mockNotificationFilterPreference("wikiA:SpaceM.DocumentN", documentReference, NotificationFilterType.INCLUSIVE, null);
    when(notificationFilterManager.getFilterPreferences(any(DocumentReference.class))).thenReturn(Sets.newSet(prefγ, prefζ));
    DocumentReference user = new DocumentReference("xwiki", "XWiki", "User");
    // Test 1
    String result = mocker.getComponentUnderTest().filterExpression(user, preference).toString();
    assertEquals("((WIKI = \"wikiA\" AND SPACE STARTS WITH \"wikiA:SpaceB\") " + "OR (WIKI = \"wikiA\" AND PAGE = \"wikiA:SpaceM.DocumentN\"))", result);
    // Test with wikiA:SpaceE (filtered by γ & ζ)
    Event event1 = mock(Event.class);
    when(event1.getSpace()).thenReturn(new SpaceReference("SpaceE", wikiReference));
    assertEquals(NotificationFilter.FilterPolicy.FILTER, mocker.getComponentUnderTest().filterEvent(event1, user, NotificationFormat.ALERT));
    // Test with wikiA:SpaceB.DocumentJ (kept by γ)
    Event event2 = mock(Event.class);
    when(event2.getDocument()).thenReturn(new DocumentReference("wikiA", "SpaceB", "DocumentJ"));
    assertEquals(NotificationFilter.FilterPolicy.NO_EFFECT, mocker.getComponentUnderTest().filterEvent(event2, user, NotificationFormat.ALERT));
    // Test with wikiB:SpaceK.DocumentL (filtered by γ & ζ)
    Event event3 = mock(Event.class);
    when(event3.getDocument()).thenReturn(new DocumentReference("wikiB", "SpaceK", "DocumentL"));
    assertEquals(NotificationFilter.FilterPolicy.FILTER, mocker.getComponentUnderTest().filterEvent(event3, user, NotificationFormat.ALERT));
    // Test with wikiA:SpaceM.DocumentN (kept by ζ)
    Event event4 = mock(Event.class);
    when(event4.getDocument()).thenReturn(new DocumentReference("wikiA", "SpaceM", "DocumentN"));
    assertEquals(NotificationFilter.FilterPolicy.NO_EFFECT, mocker.getComponentUnderTest().filterEvent(event4, user, NotificationFormat.ALERT));
}
Also used : NotificationPreference(org.xwiki.notifications.preferences.NotificationPreference) HashMap(java.util.HashMap) SpaceReference(org.xwiki.model.reference.SpaceReference) NotificationFilterPreference(org.xwiki.notifications.filters.NotificationFilterPreference) NotificationPreferenceProperty(org.xwiki.notifications.preferences.NotificationPreferenceProperty) Event(org.xwiki.eventstream.Event) WikiReference(org.xwiki.model.reference.WikiReference) DocumentReference(org.xwiki.model.reference.DocumentReference) Test(org.junit.Test)

Example 13 with NotificationPreference

use of org.xwiki.notifications.preferences.NotificationPreference in project xwiki-platform by xwiki.

the class CachedModelBridge method getNotificationsPreferences.

@Override
public List<NotificationPreference> getNotificationsPreferences(DocumentReference userReference) throws NotificationException {
    // We need to store the user reference in the cache's key, otherwise all users of the same context will share
    // the same cache, which can happen when a notification email is triggered.
    final String specificUserNotificationsPreferences = String.format(CACHE_KEY_PATTERN, USER_NOTIFICATIONS_PREFERENCES, serializer.serialize(userReference));
    ExecutionContext context = execution.getContext();
    if (context.hasProperty(specificUserNotificationsPreferences)) {
        return (List<NotificationPreference>) context.getProperty(specificUserNotificationsPreferences);
    }
    List<NotificationPreference> preferences = modelBridge.getNotificationsPreferences(userReference);
    context.setProperty(specificUserNotificationsPreferences, preferences);
    return preferences;
}
Also used : NotificationPreference(org.xwiki.notifications.preferences.NotificationPreference) ExecutionContext(org.xwiki.context.ExecutionContext) List(java.util.List)

Example 14 with NotificationPreference

use of org.xwiki.notifications.preferences.NotificationPreference in project xwiki-platform by xwiki.

the class DefaultNotificationPreferenceManager method getPreferences.

@Override
public List<NotificationPreference> getPreferences(DocumentReference user, boolean isEnabled, NotificationFormat format) throws NotificationException {
    List<NotificationPreference> preferences = getAllPreferences(user);
    Iterator<NotificationPreference> it = preferences.iterator();
    while (it.hasNext()) {
        NotificationPreference preference = it.next();
        if (preference.isNotificationEnabled() != isEnabled || !preference.getFormat().equals(format)) {
            it.remove();
        }
    }
    return preferences;
}
Also used : NotificationPreference(org.xwiki.notifications.preferences.NotificationPreference)

Example 15 with NotificationPreference

use of org.xwiki.notifications.preferences.NotificationPreference in project xwiki-platform by xwiki.

the class QueryGenerator method generateQueryExpression.

/**
 * Generate the query.
 *
 * @param user user interested in the notifications
 * @param format only match notifications enabled for that format
 * @param endDate do not return events happened after this date
 * @param startDate do not return events happened before this date. Note that since 9.7RC1, this start date is
 * completely optional, {@link NotificationPreference#getStartDate()} should be used for more granular control on
 * notifications
 * @param blackList list of ids of blacklisted events to not return (to not get already known events again)
 * @return the query to execute
 *
 * @throws NotificationException if error happens
 * @throws QueryException if error happens
 *
 * @since 9.8RC1
 */
public ExpressionNode generateQueryExpression(DocumentReference user, NotificationFormat format, Date endDate, Date startDate, List<String> blackList) throws NotificationException, QueryException {
    // First: get the active preferences of the given user
    List<NotificationPreference> preferences = notificationPreferenceManager.getPreferences(user, true, format);
    // Ensure that we have at least one filter preference that is active
    if (preferences.isEmpty() && notificationFilterManager.getFilterPreferences(user).stream().noneMatch(NotificationFilterPreference::isActive)) {
        return null;
    }
    AbstractOperatorNode topNode = null;
    // Condition 1: (maybe) events have happened after the given start date
    if (startDate != null) {
        topNode = new GreaterThanNode(new PropertyValueNode(EventProperty.DATE), new DateValueNode(startDate));
    }
    // Condition 2: handle other preferences
    AbstractOperatorNode preferencesNode = handleEventPreferences(user, preferences);
    // Condition 3: handle exclusive global notification filters
    AbstractOperatorNode globalExclusiveFiltersNode = handleExclusiveGlobalFilters(user, format);
    if (globalExclusiveFiltersNode != null) {
        if (preferencesNode == null) {
            preferencesNode = globalExclusiveFiltersNode;
        } else {
            preferencesNode = preferencesNode.and(globalExclusiveFiltersNode);
        }
    }
    // Condition 4: handle inclusive global notification filters
    AbstractOperatorNode globalInclusiveFiltersNode = handleInclusiveGlobalFilters(user, format);
    if (globalInclusiveFiltersNode != null) {
        if (preferencesNode == null) {
            preferencesNode = globalInclusiveFiltersNode;
        } else {
            preferencesNode = preferencesNode.or(globalInclusiveFiltersNode);
        }
    }
    // Mix all these conditions
    if (preferencesNode != null) {
        if (topNode != null) {
            topNode = topNode.and(preferencesNode);
        } else {
            topNode = preferencesNode;
        }
    }
    // Other basic filters
    topNode = handleBlackList(blackList, topNode);
    topNode = handleEndDate(endDate, topNode);
    topNode = handleHiddenEvents(topNode);
    topNode = handleWiki(user, topNode);
    topNode = handleOrder(topNode);
    return topNode;
}
Also used : NotificationPreference(org.xwiki.notifications.preferences.NotificationPreference) AbstractOperatorNode(org.xwiki.notifications.filters.expression.generics.AbstractOperatorNode) DateValueNode(org.xwiki.notifications.filters.expression.DateValueNode) GreaterThanNode(org.xwiki.notifications.filters.expression.GreaterThanNode) PropertyValueNode(org.xwiki.notifications.filters.expression.PropertyValueNode)

Aggregations

NotificationPreference (org.xwiki.notifications.preferences.NotificationPreference)32 Test (org.junit.Test)18 DocumentReference (org.xwiki.model.reference.DocumentReference)12 HashMap (java.util.HashMap)8 List (java.util.List)8 NotificationPreferenceProperty (org.xwiki.notifications.preferences.NotificationPreferenceProperty)8 Date (java.util.Date)7 ArrayList (java.util.ArrayList)6 WikiReference (org.xwiki.model.reference.WikiReference)5 NotificationException (org.xwiki.notifications.NotificationException)4 NotificationFormat (org.xwiki.notifications.NotificationFormat)4 NotificationFilterPreference (org.xwiki.notifications.filters.NotificationFilterPreference)4 TargetableNotificationPreference (org.xwiki.notifications.preferences.TargetableNotificationPreference)4 Map (java.util.Map)3 NotificationFilter (org.xwiki.notifications.filters.NotificationFilter)3 NotificationPreferenceManager (org.xwiki.notifications.preferences.NotificationPreferenceManager)3 Query (org.xwiki.query.Query)3 XWiki (com.xpn.xwiki.XWiki)2 XWikiContext (com.xpn.xwiki.XWikiContext)2 XWikiException (com.xpn.xwiki.XWikiException)2