You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by md...@apache.org on 2014/05/23 15:27:52 UTC
svn commit: r1597090 - in /syncope/trunk:
common/src/main/java/org/apache/syncope/common/to/
console/src/main/java/org/apache/syncope/console/pages/
console/src/main/resources/org/apache/syncope/console/pages/
console/src/test/java/org/apache/syncope/c...
Author: mdisabatino
Date: Fri May 23 13:27:52 2014
New Revision: 1597090
URL: http://svn.apache.org/r1597090
Log:
[SYNCOPE-446] Notification: added possibility to specify About for roles
Modified:
syncope/trunk/common/src/main/java/org/apache/syncope/common/to/NotificationTO.java
syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/NotificationModalPage.java
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage.html
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage.properties
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage_it.properties
syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage_pt_BR.properties
syncope/trunk/console/src/test/java/org/apache/syncope/console/ConfigurationTestITCase.java
syncope/trunk/console/src/test/java/org/apache/syncope/console/TaskTestITCase.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationManager.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/Notification.java
syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/NotificationDataBinder.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/notification/NotificationTest.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/NotificationTestITCase.java
syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
syncope/trunk/core/src/test/resources/content.xml
Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/to/NotificationTO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/NotificationTO.java?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/to/NotificationTO.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/to/NotificationTO.java Fri May 23 13:27:52 2014
@@ -41,7 +41,9 @@ public class NotificationTO extends Abst
private List<String> events = new ArrayList<String>();
- private String about;
+ private String userAbout;
+
+ private String roleAbout;
private String recipients;
@@ -63,12 +65,20 @@ public class NotificationTO extends Abst
private boolean active;
- public String getAbout() {
- return about;
+ public String getUserAbout() {
+ return userAbout;
+ }
+
+ public void setUserAbout(final String userAbout) {
+ this.userAbout = userAbout;
+ }
+
+ public String getRoleAbout() {
+ return roleAbout;
}
- public void setAbout(final String about) {
- this.about = about;
+ public void setRoleAbout(final String roleAbout) {
+ this.roleAbout = roleAbout;
}
@XmlElementWrapper(name = "events")
Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/NotificationModalPage.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/NotificationModalPage.java?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/NotificationModalPage.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/NotificationModalPage.java Fri May 23 13:27:52 2014
@@ -30,6 +30,7 @@ import org.apache.syncope.common.types.T
import org.apache.syncope.common.SyncopeClientException;
import org.apache.syncope.console.commons.Constants;
import org.apache.syncope.console.pages.panels.LoggerCategoryPanel;
+import org.apache.syncope.console.pages.panels.RoleSearchPanel;
import org.apache.syncope.console.pages.panels.UserSearchPanel;
import org.apache.syncope.console.rest.LoggerRestClient;
import org.apache.syncope.console.rest.NotificationRestClient;
@@ -66,8 +67,8 @@ class NotificationModalPage extends Base
public NotificationModalPage(final PageReference pageRef, final ModalWindow window,
final NotificationTO notificationTO, final boolean createFlag) {
- final Form<NotificationTO> form =
- new Form<NotificationTO>(FORM, new CompoundPropertyModel<NotificationTO>(notificationTO));
+ final Form<NotificationTO> form
+ = new Form<NotificationTO>(FORM, new CompoundPropertyModel<NotificationTO>(notificationTO));
final AjaxTextFieldPanel sender = new AjaxTextFieldPanel("sender", getString("sender"),
new PropertyModel<String>(notificationTO, "sender"));
@@ -106,14 +107,30 @@ class NotificationModalPage extends Base
form.add(aboutContainer);
- final AjaxCheckBoxPanel checkAbout =
- new AjaxCheckBoxPanel("checkAbout", "checkAbout",
- new Model<Boolean>(notificationTO.getAbout() == null));
+ final AjaxCheckBoxPanel checkAbout
+ = new AjaxCheckBoxPanel("checkAbout", "checkAbout",
+ new Model<Boolean>(notificationTO.getUserAbout() == null && notificationTO.getRoleAbout() == null));
aboutContainer.add(checkAbout);
- final UserSearchPanel about = new UserSearchPanel.Builder("about").fiql(notificationTO.getAbout()).build();
- aboutContainer.add(about);
- about.setEnabled(!checkAbout.getModelObject());
+ final AjaxCheckBoxPanel checkUserAbout
+ = new AjaxCheckBoxPanel("checkUserAbout", "checkUserAbout",
+ new Model<Boolean>(notificationTO.getUserAbout() != null));
+ aboutContainer.add(checkUserAbout);
+
+ final AjaxCheckBoxPanel checkRoleAbout
+ = new AjaxCheckBoxPanel("checkRoleAbout", "checkRoleAbout",
+ new Model<Boolean>(notificationTO.getRoleAbout() != null));
+ aboutContainer.add(checkRoleAbout);
+
+ final UserSearchPanel userAbout
+ = new UserSearchPanel.Builder("userAbout").fiql(notificationTO.getUserAbout()).build();
+ aboutContainer.add(userAbout);
+ userAbout.setEnabled(checkUserAbout.getModelObject());
+
+ final RoleSearchPanel roleAbout
+ = new RoleSearchPanel.Builder("roleAbout").fiql(notificationTO.getRoleAbout()).build();
+ aboutContainer.add(roleAbout);
+ roleAbout.setEnabled(checkRoleAbout.getModelObject());
checkAbout.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
@@ -121,8 +138,50 @@ class NotificationModalPage extends Base
@Override
protected void onUpdate(final AjaxRequestTarget target) {
- about.setEnabled(!checkAbout.getModelObject());
- target.add(about);
+ if (checkAbout.getModelObject()) {
+ checkUserAbout.setModelObject(Boolean.FALSE);
+ checkRoleAbout.setModelObject(Boolean.FALSE);
+ userAbout.setEnabled(Boolean.FALSE);
+ roleAbout.setEnabled(Boolean.FALSE);
+ } else {
+ checkAbout.setModelObject(Boolean.TRUE);
+ }
+ target.add(aboutContainer);
+ }
+ });
+
+ checkUserAbout.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ if (checkUserAbout.getModelObject()) {
+ checkAbout.setModelObject(!checkUserAbout.getModelObject());
+ checkRoleAbout.setModelObject(!checkUserAbout.getModelObject());
+ roleAbout.setEnabled(Boolean.FALSE);
+ } else {
+ checkUserAbout.setModelObject(Boolean.TRUE);
+ }
+ userAbout.setEnabled(Boolean.TRUE);
+ target.add(aboutContainer);
+ }
+ });
+
+ checkRoleAbout.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+ private static final long serialVersionUID = -1107858522700306810L;
+
+ @Override
+ protected void onUpdate(final AjaxRequestTarget target) {
+ if (checkRoleAbout.getModelObject()) {
+ checkAbout.setModelObject(Boolean.FALSE);
+ checkUserAbout.setModelObject(Boolean.FALSE);
+ userAbout.setEnabled(Boolean.FALSE);
+ } else {
+ checkRoleAbout.setModelObject(Boolean.TRUE);
+ }
+ roleAbout.setEnabled(Boolean.TRUE);
target.add(aboutContainer);
}
});
@@ -165,12 +224,12 @@ class NotificationModalPage extends Base
@Override
protected String[] getListRoles() {
- return new String[] {};
+ return new String[]{};
}
@Override
protected String[] getChangeRoles() {
- return new String[] {};
+ return new String[]{};
}
});
@@ -293,7 +352,11 @@ class NotificationModalPage extends Base
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
- notificationTO.setAbout(checkAbout.getModelObject() ? null : about.buildFIQL());
+ notificationTO.setUserAbout(
+ !checkAbout.getModelObject() && checkUserAbout.getModelObject() ? userAbout.buildFIQL() : null);
+ notificationTO.setRoleAbout(
+ !checkAbout.getModelObject()
+ && checkRoleAbout.getModelObject() ? roleAbout.buildFIQL() : null);
notificationTO.setRecipients(checkRecipients.getModelObject() ? recipients.buildFIQL() : null);
notificationTO.getStaticRecipients().removeAll(Collections.singleton(null));
Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage.html?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage.html Fri May 23 13:27:52 2014
@@ -134,10 +134,18 @@ under the License.
<div class="tablecolumn_field" style="width: auto; padding-right: 5px;">
<span wicket:id="checkAbout">[checkAbout]</span>
</div>
- <div class="tablecolumn_label" style="width: auto;">
+ <div class="tablecolumn_label" style="width: 100%">
<label for="checkAbout"><wicket:message key="checkAbout"/></label>
</div>
</div>
+ <div class="tablerow" style="width: auto;">
+ <div class="tablecolumn_field" style="width: auto; padding-right: 5px;">
+ <span wicket:id="checkUserAbout">[checkUserAbout]</span>
+ </div>
+ <div class="tablecolumn_label" style="width: auto;">
+ <label for="checkUserAbout"><wicket:message key="checkUserAbout"/></label>
+ </div>
+ </div>
<div id="userFilter">
<div id="title">
<label for="userFilter"><wicket:message key="userFilter"/></label>
@@ -146,7 +154,26 @@ under the License.
<label for="userFilter"><wicket:message key="userFilterWarning"/></label>
</div>
<div id="condition">
- <span wicket:id="about"/>
+ <span wicket:id="userAbout"/>
+ </div>
+ </div>
+ <div class="tablerow" style="width: auto;">
+ <div class="tablecolumn_field" style="width: auto; padding-right: 5px;">
+ <span wicket:id="checkRoleAbout">[checkRoleAbout]</span>
+ </div>
+ <div class="tablecolumn_label" style="width: auto;">
+ <label for="checkRoleAbout"><wicket:message key="checkRoleAbout"/></label>
+ </div>
+ </div>
+ <div id="userFilter">
+ <div id="title">
+ <label for="roleFilter"><wicket:message key="roleFilter"/></label>
+ </div>
+ <div id="warning">
+ <label for="roleFilter"><wicket:message key="roleFilterWarning"/></label>
+ </div>
+ <div id="condition">
+ <span wicket:id="roleAbout"/>
</div>
</div>
</span>
@@ -192,7 +219,7 @@ under the License.
</div>
</div>
</div>
-
+
<div style="margin: 20px 10px 0">
<input type="submit"
class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage.properties?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage.properties Fri May 23 13:27:52 2014
@@ -33,4 +33,8 @@ userFilter=User filter
userFilterWarning=Do not use this filter unless events are not targeted at users
userNotifications=User notifications
userNotificationsWarning=Do not select this checkbox unless events are not targeted at users
+roleFilter=Role filter
+roleFilterWarning=Do not use this filter unless events are not targeted at roles
isActive=Enabled
+checkUserAbout=Users
+checkRoleAbout=Roles
Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage_it.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage_it.properties?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage_it.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage_it.properties Fri May 23 13:27:52 2014
@@ -33,4 +33,8 @@ userFilter=Filtro utenti
userFilterWarning=Non usare questo filtro se gli eventi catturati non riguardano espressamente utenti
userNotifications=Notifiche utente
userNotificationsWarning=Non selezionare questa checkbox se gli eventi catturati non riguardano espressamente utenti
+roleFilter=Filtro ruoli
+roleFilterWarning=Non usare questo filtro se gli eventi catturati non riguardano espressamente i ruoli
isActive=Abilitata
+checkUserAbout=Utenti
+checkRoleAbout=Ruoli
Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage_pt_BR.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage_pt_BR.properties?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage_pt_BR.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/NotificationModalPage_pt_BR.properties Fri May 23 13:27:52 2014
@@ -33,4 +33,8 @@ userFilter=User filter
userFilterWarning=N\u00e3o use este filtro n\u00e3o ser que os eventos n\u00e3o s\u00e3o direcionados a usu\u00e1rios
userNotifications=Notifica\u00e7\u00f5es do usu\u00e1rio
userNotificationsWarning=N\u00e3o selecione esta op\u00e7\u00e3o a menos que os eventos n\u00e3o s\u00e3o direcionados a usu\u00e1rios
-isActive=Ativada
\ No newline at end of file
+roleNotifications=Notifica\u00e7\u00f5es do fun\u00e7\u00f5es
+roleNotificationsWarning=N\u00e3o selecione esta op\u00e7\u00e3o a menos que os eventos n\u00e3o s\u00e3o direcionados a fun\u00e7\u00f5es
+isActive=Ativada
+checkUserAbout=Usu\u00e1rio
+checkRoleAbout=Fun\u00e7\u00e3o
Modified: syncope/trunk/console/src/test/java/org/apache/syncope/console/ConfigurationTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/test/java/org/apache/syncope/console/ConfigurationTestITCase.java?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/console/src/test/java/org/apache/syncope/console/ConfigurationTestITCase.java (original)
+++ syncope/trunk/console/src/test/java/org/apache/syncope/console/ConfigurationTestITCase.java Fri May 23 13:27:52 2014
@@ -138,7 +138,7 @@ public class ConfigurationTestITCase ext
selenium.type("name=sender:textField", "test@syncope.it");
- selenium.type("name=sender:textField", "test@syncope.it");
+ selenium.type("name=subject:textField", "test@syncope.it");
selenium.select("//div[2]/form/div[3]/div/div/div[3]/div[2]/span/select", "label=UserSchema");
@@ -168,7 +168,7 @@ public class ConfigurationTestITCase ext
+ "//select[@name='eventSelection:categoryContainer:category:dropDownChoiceField']"
+ "/option[text()='role']\");",
"30000");
-
+
selenium.select(
"//select[@name='eventSelection:categoryContainer:category:dropDownChoiceField']",
"label=role");
@@ -189,7 +189,7 @@ public class ConfigurationTestITCase ext
selenium.click("//div[@class='eventSelectionWidzard']/div[2]/div[3]/span/div/input");
selenium.click("//div[2]/form/div[3]/ul/li[4]/a/span");
-
+
selenium.click("//div[2]/form/div[3]/div[4]/div/div/span/input");
selenium.type(
@@ -238,7 +238,7 @@ public class ConfigurationTestITCase ext
// disable notification
selenium.click("//div[2]/form/div[3]/div/div/div[7]/div[2]/span/input");
-
+
selenium.click("//div[2]/form/div[3]/ul/li[3]/a/span");
selenium.click("//div[2]/form/div[3]/ul/li[2]/a/span");
@@ -256,7 +256,7 @@ public class ConfigurationTestITCase ext
+ "//select[@name='eventSelection:categoryContainer:category:dropDownChoiceField']"
+ "/option[text()='role']\");",
"30000");
-
+
selenium.select(
"//select[@name='eventSelection:categoryContainer:category:dropDownChoiceField']",
"label=role");
@@ -277,7 +277,7 @@ public class ConfigurationTestITCase ext
selenium.click("//div[@class='eventSelectionWidzard']/div[2]/div[3]/span/div/input");
selenium.click("//div[2]/form/div[3]/ul/li[4]/a/span");
-
+
selenium.click("//div[2]/form/div[3]/div[4]/div/div/span/input");
selenium.type(
@@ -290,7 +290,7 @@ public class ConfigurationTestITCase ext
seleniumDriver.switchTo().defaultContent();
}
-
+
@Test
public void issueSYNCOPE189() {
selenium.click("css=img[alt=\"Configuration\"]");
@@ -308,4 +308,98 @@ public class ConfigurationTestITCase ext
seleniumDriver.switchTo().defaultContent();
}
+
+ @Test
+ public void issueSYNCOPE446() {
+ selenium.click("css=img[alt=\"Configuration\"]");
+
+ selenium.waitForCondition("selenium.isElementPresent(\"//div[@id='tabs']\");", "30000");
+
+ selenium.click("//div[@id='tabs']/ul/li[3]/a");
+
+ selenium.click("//a[contains(text(),'Create new notification')]");
+
+ selenium.waitForCondition("selenium.isElementPresent("
+ + "\"//div[2]/form/div[3]/div/div/div/div/label\");", "30000");
+
+ selenium.waitForCondition("selenium.isElementPresent(\"//input[@name='sender:textField']\");", "30000");
+
+ selenium.waitForCondition("selenium.isElementPresent(\"//iframe\");", "30000");
+ selenium.selectFrame("index=0");
+
+ selenium.type("name=sender:textField", "syncope446@syncope.it");
+
+ selenium.type("name=subject:textField", "Test issue Syncope 446");
+
+ selenium.select("//div[2]/form/div[3]/div/div/div[3]/div[2]/span/select", "label=UserSchema");
+
+ selenium.waitForCondition("selenium.isElementPresent("
+ + "\"//div[2]/form/div[3]/div/div/div[4]/div[2]/span/select/option[2]\");", "30000");
+
+ selenium.select("//div[2]/form/div[3]/div/div/div[4]/div[2]/span/select", "label=email");
+
+ selenium.select("//div[2]/form/div[3]/div/div/div[5]/div[2]/span/select", "label=optin");
+
+ selenium.select("//div[2]/form/div[3]/div/div/div[6]/div[2]/span/select", "label=ALL");
+
+ selenium.click("//div[2]/form/div[3]/ul/li[3]/a/span");
+
+ selenium.click("//div[2]/form/div[3]/ul/li[2]/a/span");
+
+ selenium.waitForCondition("selenium.isElementPresent(\""
+ + "//select[@name='eventSelection:categoryContainer:type:dropDownChoiceField']"
+ + "/option[text()='REST']\");",
+ "30000");
+
+ selenium.select(
+ "//select[@name='eventSelection:categoryContainer:type:dropDownChoiceField']",
+ "label=REST");
+
+ selenium.waitForCondition("selenium.isElementPresent(\""
+ + "//select[@name='eventSelection:categoryContainer:category:dropDownChoiceField']"
+ + "/option[text()='RoleController']\");",
+ "30000");
+
+ selenium.select(
+ "//select[@name='eventSelection:categoryContainer:category:dropDownChoiceField']",
+ "label=RoleController");
+
+ selenium.waitForCondition("selenium.isElementPresent("
+ + "\"//input[@name='eventSelection:eventsContainer:eventsPanel:successGroup']\");",
+ "30000");
+
+ selenium.click("//div[@class='eventSelectionWidzard']/div[2]/div[3]/span/div/input");
+
+ selenium.click("//div[2]/form/div[3]/ul/li[3]/a/span");
+ selenium.click("//div[2]/form/div[3]/div[3]/span/div[4]/div/span/input");
+
+ selenium.waitForCondition("selenium.isElementPresent(\""
+ + "//select[@name='aboutContainer:roleAbout:searchFormContainer:searchView:0:type']"
+ + "/option[text()='ENTITLEMENT']\");",
+ "30000");
+
+ selenium.select(
+ "//select[@name='aboutContainer:roleAbout:searchFormContainer:searchView:0:type']",
+ "label=ENTITLEMENT");
+
+ selenium.waitForCondition("selenium.isElementPresent(\""
+ + "//select[@name='aboutContainer:roleAbout:searchFormContainer:searchView:0:property']"
+ + "/option[text()='ROLE_CREATE']\");",
+ "30000");
+
+ selenium.select(
+ "//select[@name='aboutContainer:roleAbout:searchFormContainer:searchView:0:property']",
+ "label=ROLE_CREATE");
+
+ selenium.click("//div[2]/form/div[3]/ul/li[4]/a/span");
+
+ selenium.click("//input[@name='recipientsContainer:checkRecipients:checkboxField']");
+
+ selenium.type(
+ "name=staticRecipients:multiValueContainer:view:0:panel:textField", "syncope446@syncope.apache.org");
+
+ selenium.click("//div[2]/form/div[4]/input");
+
+ seleniumDriver.switchTo().defaultContent();
+ }
}
Modified: syncope/trunk/console/src/test/java/org/apache/syncope/console/TaskTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/test/java/org/apache/syncope/console/TaskTestITCase.java?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/console/src/test/java/org/apache/syncope/console/TaskTestITCase.java (original)
+++ syncope/trunk/console/src/test/java/org/apache/syncope/console/TaskTestITCase.java Fri May 23 13:27:52 2014
@@ -28,30 +28,30 @@ public class TaskTestITCase extends Abst
selenium.waitForCondition("selenium.isElementPresent(\"//div[@id='tabs']\");", "30000");
- selenium.click("//div[@id='tabs']/ul/li[4]/a");
+ selenium.click("//div[@id='tabs']/ul/li[1]/a");
selenium.waitForCondition("selenium.isElementPresent("
- + "\"//div[4]/span/div/span/span/span/form/span/table/tbody/tr/td[9]/div/span[6]/a/img\");", "30000");
+ + "\"//tr[4]/td[10]/div/span[6]/a/img\");", "30000");
- selenium.click("//div[4]/span/div/span/span/span/form/span/table/tbody/tr/td[9]/div/span[6]/a/img");
-
- selenium.waitForCondition("selenium.isTextPresent(" + "\"Operation executed successfully\");", "30000");
+ selenium.click("//tr[4]/td[10]/div/span[6]/a/img");
+
+ selenium.waitForCondition("selenium.isTextPresent(\"Operation executed successfully\");", "30000");
selenium.waitForCondition("selenium.isElementPresent("
- + "\"//div[4]/span/div/span/span/span/form/span/table/tbody/tr/td[9]/div/span[12]/a/img\");", "30000");
-
- selenium.click("//div[4]/span/div/span/span/span/form/span/table/tbody/tr/td[9]/div/span[12]/a/img");
+ + "\"//tr[4]/td[10]/div/span[12]/a/img\");", "30000");
+
+ selenium.click("//tr[4]/td[10]/div/span[12]/a/img");
selenium.waitForCondition("selenium.isElementPresent(\"//iframe\");", "30000");
selenium.selectFrame("index=0");
selenium.waitForCondition("selenium.isElementPresent("
- + "\"//div[2]/form/div[2]/ul/li[3]/a\");", "30000");
-
- selenium.click("//div[2]/form/div[2]/ul/li[3]/a");
+ + "\"//div[2]/form/div[2]/ul/li[2]/a\");", "30000");
- assertTrue(selenium.isElementPresent("//div[2]/form/div[2]/div[3]/span/table/tbody/tr/td[2]"));
+ selenium.click("//div[2]/form/div[2]/ul/li[2]/a");
+ assertTrue(selenium.isElementPresent("//div[2]/form/div[2]/div[2]/span/table/tbody/tr/td[4]"));
+
seleniumDriver.switchTo().defaultContent();
selenium.click("css=a.w_close");
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationManager.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationManager.java?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationManager.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationManager.java Fri May 23 13:27:52 2014
@@ -41,6 +41,7 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.beans.NotificationTask;
import org.apache.syncope.core.persistence.beans.SyncopeConf;
import org.apache.syncope.core.persistence.beans.TaskExec;
+import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
import org.apache.syncope.core.persistence.beans.user.UAttr;
import org.apache.syncope.core.persistence.beans.user.UDerAttr;
@@ -53,6 +54,7 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.dao.TaskDAO;
import org.apache.syncope.core.persistence.dao.UserDAO;
import org.apache.syncope.core.persistence.dao.search.OrderByClause;
+import org.apache.syncope.core.rest.data.RoleDataBinder;
import org.apache.syncope.core.rest.data.SearchCondConverter;
import org.apache.syncope.core.rest.data.UserDataBinder;
import org.apache.syncope.core.util.AttributableUtil;
@@ -72,7 +74,7 @@ import org.springframework.transaction.a
*
* @see NotificationTask
*/
-@Transactional(rollbackFor = { Throwable.class })
+@Transactional(rollbackFor = {Throwable.class})
public class NotificationManager {
/**
@@ -111,6 +113,12 @@ public class NotificationManager {
private UserDataBinder userDataBinder;
/**
+ * Role data binder.
+ */
+ @Autowired
+ private RoleDataBinder roleDataBinder;
+
+ /**
* User Search DAO.
*/
@Autowired
@@ -154,7 +162,9 @@ public class NotificationManager {
final Map<String, Object> model) {
if (attributable != null) {
- connObjectUtil.retrieveVirAttrValues(attributable, AttributableUtil.getInstance(AttributableType.USER));
+ connObjectUtil.retrieveVirAttrValues(attributable,
+ AttributableUtil.getInstance(
+ attributable instanceof SyncopeUser ? AttributableType.USER : AttributableType.ROLE));
}
final List<SyncopeUser> recipients = new ArrayList<SyncopeUser>();
@@ -268,7 +278,8 @@ public class NotificationManager {
LOG.debug("Search notification for [{}]{}", attributableType, attributable);
for (Notification notification : notificationDAO.findAll()) {
- LOG.debug("Notification available about {}", notification.getAbout());
+ LOG.debug("Notification available user about {}", notification.getUserAbout());
+ LOG.debug("Notification available role about {}", notification.getRoleAbout());
if (notification.isActive()) {
final Set<String> events = new HashSet<String>(notification.getEvents());
@@ -277,9 +288,13 @@ public class NotificationManager {
if (events.isEmpty()) {
LOG.debug("No events found about {}", attributable);
- } else if (attributableType == null || attributable == null || notification.
- getAbout() == null || searchDAO.matches(attributable,
- SearchCondConverter.convert(notification.getAbout()),
+ } else if (attributableType == null || attributable == null
+ || notification.getUserAbout() == null || notification.getRoleAbout() == null
+ || searchDAO.matches(attributable,
+ SearchCondConverter.convert(notification.getUserAbout()),
+ AttributableUtil.getInstance(attributableType))
+ || searchDAO.matches(attributable,
+ SearchCondConverter.convert(notification.getRoleAbout()),
AttributableUtil.getInstance(attributableType))) {
LOG.debug("Creating notification task for events {} about {}", events, attributable);
@@ -296,13 +311,16 @@ public class NotificationManager {
if (attributable instanceof SyncopeUser) {
model.put("user", userDataBinder.getUserTO((SyncopeUser) attributable));
+ } else if (attributable instanceof SyncopeRole) {
+ model.put("role", roleDataBinder.getRoleTO((SyncopeRole) attributable));
}
taskDAO.save(getNotificationTask(notification, attributable, model));
}
} else {
- LOG.debug("Notification {}, about {} is deactivated, notification task will not be created",
- notification.getId(), notification.getAbout());
+ LOG.debug("Notification {}, userAbout {}, roleAbout {} is deactivated, "
+ + "notification task will not be created", notification.getId(),
+ notification.getUserAbout(), notification.getRoleAbout());
}
}
}
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/Notification.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/Notification.java?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/Notification.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/Notification.java Fri May 23 13:27:52 2014
@@ -50,7 +50,9 @@ public class Notification extends Abstra
@Column(name = "events")
private List<String> events;
- private String about;
+ private String userAbout;
+
+ private String roleAbout;
private String recipients;
@@ -102,12 +104,20 @@ public class Notification extends Abstra
return id;
}
- public String getAbout() {
- return about;
+ public String getUserAbout() {
+ return userAbout;
+ }
+
+ public void setUserAbout(final String userAbout) {
+ this.userAbout = userAbout;
+ }
+
+ public String getRoleAbout() {
+ return roleAbout;
}
- public void setAbout(final String about) {
- this.about = about;
+ public void setRoleAbout(final String roleAbout) {
+ this.roleAbout = roleAbout;
}
public String getRecipients() {
Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/NotificationDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/NotificationDataBinder.java?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/NotificationDataBinder.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/NotificationDataBinder.java Fri May 23 13:27:52 2014
@@ -34,7 +34,8 @@ public class NotificationDataBinder {
BeanUtils.copyProperties(notification, result, IGNORE_PROPERTIES);
result.setId(notification.getId());
- result.setAbout(notification.getAbout());
+ result.setUserAbout(notification.getUserAbout());
+ result.setRoleAbout(notification.getRoleAbout());
result.setRecipients(notification.getRecipients());
return result;
@@ -49,7 +50,8 @@ public class NotificationDataBinder {
public void updateNotification(final Notification notification, final NotificationTO notificationTO) {
BeanUtils.copyProperties(notificationTO, notification, IGNORE_PROPERTIES);
- notification.setAbout(notificationTO.getAbout());
+ notification.setUserAbout(notificationTO.getUserAbout());
+ notification.setRoleAbout(notificationTO.getRoleAbout());
notification.setRecipients(notificationTO.getRecipients());
}
}
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/notification/NotificationTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/notification/NotificationTest.java?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/notification/NotificationTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/notification/NotificationTest.java Fri May 23 13:27:52 2014
@@ -41,6 +41,7 @@ import org.apache.syncope.client.Syncope
import org.apache.syncope.common.SyncopeConstants;
import org.apache.syncope.common.to.MembershipTO;
import org.apache.syncope.common.to.NotificationTaskTO;
+import org.apache.syncope.common.to.RoleTO;
import org.apache.syncope.common.to.UserTO;
import org.apache.syncope.common.types.IntMappingType;
import org.apache.syncope.common.types.TraceLevel;
@@ -53,6 +54,7 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.dao.NotificationDAO;
import org.apache.syncope.core.persistence.dao.TaskDAO;
import org.apache.syncope.core.rest.UserTestITCase;
+import org.apache.syncope.core.rest.controller.RoleController;
import org.apache.syncope.core.rest.controller.TaskController;
import org.apache.syncope.core.rest.controller.UserController;
import org.junit.AfterClass;
@@ -125,6 +127,9 @@ public class NotificationTest {
private UserController userController;
@Autowired
+ private RoleController roleController;
+
+ @Autowired
private TaskController taskController;
@Autowired
@@ -209,7 +214,7 @@ public class NotificationTest {
// 1. create suitable notification for subsequent tests
Notification notification = new Notification();
notification.addEvent("[REST]:[UserController]:[]:[create]:[SUCCESS]");
- notification.setAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+ notification.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(8L).query());
notification.setSelfAsRecipient(true);
@@ -267,7 +272,7 @@ public class NotificationTest {
// 1. create suitable notification for subsequent tests
Notification notification = new Notification();
notification.addEvent("[REST]:[UserController]:[]:[create]:[SUCCESS]");
- notification.setAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+ notification.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(8L).query());
notification.setSelfAsRecipient(true);
@@ -319,7 +324,7 @@ public class NotificationTest {
// 1. create suitable notification for subsequent tests
Notification notification = new Notification();
notification.addEvent("[REST]:[UserController]:[]:[create]:[SUCCESS]");
- notification.setAbout(null);
+ notification.setUserAbout(null);
notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(8L).query());
notification.setSelfAsRecipient(true);
@@ -369,7 +374,7 @@ public class NotificationTest {
// 1. create suitable notification for subsequent tests
Notification notification = new Notification();
notification.addEvent("[REST]:[UserController]:[]:[create]:[SUCCESS]");
- notification.setAbout(null);
+ notification.setUserAbout(null);
notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(8L).query());
notification.setSelfAsRecipient(true);
@@ -435,7 +440,7 @@ public class NotificationTest {
// 1. create suitable notification for subsequent tests
Notification notification = new Notification();
notification.addEvent("[REST]:[UserController]:[]:[create]:[SUCCESS]");
- notification.setAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+ notification.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(8L).query());
notification.setSelfAsRecipient(true);
@@ -494,7 +499,7 @@ public class NotificationTest {
// 1. create suitable disabled notification for subsequent tests
Notification notification = new Notification();
notification.addEvent("[REST]:[UserController]:[]:[create]:[SUCCESS]");
- notification.setAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+ notification.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
notification.setSelfAsRecipient(true);
notification.setRecipientAttrName("email");
@@ -531,4 +536,63 @@ public class NotificationTest {
// 4. check if number of tasks is not incremented
assertEquals(tasksNumberBefore, taskDAO.findAll(NotificationTask.class).size());
}
+
+ @Test
+ public void issueSYNCOPE446() throws Exception {
+
+ // 1. create suitable notification for subsequent tests
+ Notification notification = new Notification();
+ notification.addEvent("[REST]:[RoleController]:[]:[create]:[SUCCESS]");
+ notification.setRoleAbout(SyncopeClient.getRoleSearchConditionBuilder().is("name").equalTo("role446").query());
+ notification.setSelfAsRecipient(false);
+
+ notification.setRecipientAttrName("email");
+ notification.setRecipientAttrType(IntMappingType.UserSchema);
+
+ notification.getStaticRecipients().add(mailAddress);
+
+ Random random = new Random(System.currentTimeMillis());
+ String sender = "syncopetest-" + random.nextLong() + "@syncope.apache.org";
+ notification.setSender(sender);
+ String subject = "Test notification " + random.nextLong();
+ notification.setSubject(subject);
+ notification.setTemplate("optin");
+
+ Notification actual = notificationDAO.save(notification);
+ assertNotNull(actual);
+
+ notificationDAO.flush();
+
+ // 2. create role
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName("role446");
+ roleTO.setParent(1L);
+
+ RoleTO createdRole = roleController.create(roleTO);
+ assertNotNull(createdRole);
+
+ // 3. force Quartz job execution and verify e-mail
+ notificationJob.execute(null);
+ assertTrue(verifyMail(sender, subject));
+
+ // 4. get NotificationTask id and text body
+ Long taskId = null;
+ String textBody = null;
+ Set<String> recipients = null;
+ for (NotificationTask task : taskDAO.findAll(NotificationTask.class)) {
+ if (sender.equals(task.getSender())) {
+ taskId = task.getId();
+ textBody = task.getTextBody();
+ recipients = task.getRecipients();
+ }
+ }
+
+ assertNotNull(taskId);
+ assertNotNull(textBody);
+ assertTrue(recipients.contains(mailAddress));
+
+ // 5. execute Notification task and verify e-mail
+ taskController.execute(taskId, false);
+ assertTrue(verifyMail(sender, subject));
+ }
}
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java Fri May 23 13:27:52 2014
@@ -18,13 +18,10 @@
*/
package org.apache.syncope.core.persistence.dao;
-import java.util.ArrayList;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-
import java.util.List;
-
import org.apache.syncope.client.SyncopeClient;
import org.apache.syncope.common.types.IntMappingType;
import org.apache.syncope.core.persistence.beans.Notification;
@@ -44,7 +41,7 @@ public class NotificationTest extends Ab
assertNotNull(notification);
assertNotNull(notification.getEvents());
assertFalse(notification.getEvents().isEmpty());
- assertNotNull(notification.getAbout());
+ assertNotNull(notification.getUserAbout());
assertNotNull(notification.getRecipients());
}
@@ -61,7 +58,7 @@ public class NotificationTest extends Ab
Notification notification = new Notification();
notification.addEvent("save");
- notification.setAbout(SyncopeClient.getUserSearchConditionBuilder().
+ notification.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().
is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query());
notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
@@ -89,16 +86,16 @@ public class NotificationTest extends Ab
Notification notification = new Notification();
notification.addEvent("save");
- notification.setAbout(SyncopeClient.getUserSearchConditionBuilder().
+ notification.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().
is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query());
notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
notification.setRecipientAttrName("email");
notification.setRecipientAttrType(IntMappingType.UserSchema);
-
+
notification.addStaticRecipient("syncope445@syncope.apache.org");
-
+
notification.setSender("syncope@syncope.apache.org");
notification.setSubject("Test notification");
notification.setTemplate("test");
@@ -110,4 +107,27 @@ public class NotificationTest extends Ab
assertFalse(actual.getStaticRecipients().isEmpty());
}
+ @Test
+ public void issueSYNCOPE446() {
+ Notification notification = new Notification();
+ notification.addEvent("[REST]:[RoleController]:[]:[create]:[SUCCESS]");
+
+ notification.setRoleAbout(
+ SyncopeClient.getRoleSearchConditionBuilder().hasEntitlements("ROLE_READ").query());
+
+ notification.setRecipientAttrName("email");
+ notification.setRecipientAttrType(IntMappingType.UserSchema);
+
+ notification.addStaticRecipient("syncope446@syncope.apache.org");
+
+ notification.setSender("syncope@syncope.apache.org");
+ notification.setSubject("Test notification");
+ notification.setTemplate("test");
+
+ Notification actual = notificationDAO.save(notification);
+ assertNotNull(actual);
+ assertNotNull(actual.getId());
+ assertNotNull(actual.getStaticRecipients());
+ assertFalse(actual.getStaticRecipients().isEmpty());
+ }
}
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/NotificationTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/NotificationTestITCase.java?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/NotificationTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/NotificationTestITCase.java Fri May 23 13:27:52 2014
@@ -44,13 +44,13 @@ public class NotificationTestITCase exte
NotificationTO notificationTO = new NotificationTO();
notificationTO.setTraceLevel(TraceLevel.SUMMARY);
notificationTO.getEvents().add("create");
-
- notificationTO.setAbout(SyncopeClient.getUserSearchConditionBuilder().
+
+ notificationTO.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().
is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query());
notificationTO.setRecipientAttrName("email");
notificationTO.setRecipientAttrType(IntMappingType.UserSchema);
-
+
notificationTO.setSender("syncope@syncope.apache.org");
notificationTO.setSubject("Test notification");
notificationTO.setTemplate("test");
@@ -152,4 +152,22 @@ public class NotificationTestITCase exte
assertEquals(actual, notificationTO);
}
+ @Test
+ public void issueSYNCOPE446() {
+ NotificationTO notificationTO = buildNotificationTO();
+ notificationTO.getStaticRecipients().add("syncope446@syncope.apache.org");
+ notificationTO.setRoleAbout(SyncopeClient.getRoleSearchConditionBuilder().hasEntitlements("ROLE_READ").query());
+
+ NotificationTO actual = null;
+ try {
+ Response response = notificationService.create(notificationTO);
+ actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+ } catch (SyncopeClientException e) {
+ assertNotNull(e);
+ }
+ assertNotNull(actual);
+ assertNotNull(actual.getId());
+ notificationTO.setId(actual.getId());
+ assertEquals(actual, notificationTO);
+ }
}
Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java Fri May 23 13:27:52 2014
@@ -538,7 +538,7 @@ public class TaskTestITCase extends Abst
notification.setTraceLevel(TraceLevel.FAILURES);
notification.getEvents().add("[REST]:[UserController]:[]:[create]:[SUCCESS]");
- notification.setAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+ notification.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(8L).query());
notification.setSelfAsRecipient(true);
Modified: syncope/trunk/core/src/test/resources/content.xml
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/resources/content.xml?rev=1597090&r1=1597089&r2=1597090&view=diff
==============================================================================
--- syncope/trunk/core/src/test/resources/content.xml (original)
+++ syncope/trunk/core/src/test/resources/content.xml Fri May 23 13:27:52 2014
@@ -845,7 +845,7 @@ under the License.
jobClassName="org.apache.syncope.core.sync.impl.PushJob"/>
<Notification id="1" sender="test@syncope.apache.org" subject="Test subject" template="test" selfAsRecipient="0" traceLevel="ALL"
- about="fullname==*o*;fullname==*i*"
+ userAbout="fullname==*o*;fullname==*i*"
recipients="$roles==7"
recipientAttrType="UserSchema" recipientAttrName="email" active="1"/>
<Notification_events Notification_id="1" events="[CUSTOM]:[]:[]:[unexisting1]:[FAILURE]"/>