syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From skylar...@apache.org
Subject [syncope] branch master updated: [SYNCOPE-1439] Fixed user membership attributes not updated in some cases
Date Thu, 07 Mar 2019 11:21:36 GMT
This is an automated email from the ASF dual-hosted git repository.

skylark17 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new 950e11d  [SYNCOPE-1439] Fixed user membership attributes not updated in some cases
950e11d is described below

commit 950e11d101b690daf30c6927bb793d0b159d01ed
Author: skylark17 <matteo.alessandroni@tirasa.net>
AuthorDate: Thu Mar 7 10:37:22 2019 +0100

    [SYNCOPE-1439] Fixed user membership attributes not updated in some cases
---
 .../markup/html/form/AbstractMultiPanel.java       |   1 +
 .../console/wizards/any/AnyWizardBuilder.java      |   6 +-
 .../client/console/wizards/any/PlainAttrs.java     | 152 ++++++++++++---
 .../apache/syncope/fit/console/UsersITCase.java    | 213 +++++++++++++++++++++
 4 files changed, 346 insertions(+), 26 deletions(-)

diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractMultiPanel.java
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractMultiPanel.java
index 6d3be21..925e8e6 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractMultiPanel.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/AbstractMultiPanel.java
@@ -60,6 +60,7 @@ public abstract class AbstractMultiPanel<INNER> extends AbstractFieldPanel<List<
 
         form = new Form<>("innerForm");
         form.setDefaultButton(null);
+        form.setMultiPart(true);
         container.add(form);
         // -----------------------
 
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
index e91e667..b4ca67b 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/AnyWizardBuilder.java
@@ -186,14 +186,15 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends
AjaxWizardBuilde
                 updated.getVirAttrs().add(virAttr);
             }
         }
+
         if (updated instanceof GroupableRelatableTO && original instanceof GroupableRelatableTO)
{
             GroupableRelatableTO.class.cast(original).getMemberships().forEach(oMemb ->
{
                 GroupableRelatableTO.class.cast(updated).getMembership(oMemb.getGroupKey()).ifPresent(uMemb
-> {
                     oMemb.getPlainAttrs().stream().
-                            filter(attr -> uMemb.getPlainAttr(attr.getSchema()).isPresent()).
+                            filter(attr -> !uMemb.getPlainAttr(attr.getSchema()).isPresent()).
                             forEach(attr -> uMemb.getPlainAttrs().add(attr));
                     oMemb.getVirAttrs().stream().
-                            filter(attr -> uMemb.getVirAttr(attr.getSchema()).isPresent()).
+                            filter(attr -> !uMemb.getVirAttr(attr.getSchema()).isPresent()).
                             forEach(attr -> uMemb.getVirAttrs().add(attr));
                 });
             });
@@ -210,4 +211,5 @@ public abstract class AnyWizardBuilder<A extends AnyTO> extends
AjaxWizardBuilde
             });
         }
     }
+
 }
diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
index 7d68c0c..8d82acb 100644
--- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
+++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.wizards.any;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -47,7 +48,8 @@ import org.apache.syncope.common.lib.EntityTOUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.Attr;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.AttributableTO;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.GroupableRelatableTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
@@ -64,6 +66,7 @@ import org.apache.wicket.markup.html.form.IChoiceRenderer;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.ResourceModel;
@@ -113,7 +116,7 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
 
             @Override
             public WebMarkupContainer getPanel(final String panelId) {
-                return new PlainSchemas(panelId, schemas, attrs);
+                return new PlainSchemasOwn(panelId, schemas, attrTOs);
             }
         }), Model.of(0)).setOutputMarkupId(true));
 
@@ -134,10 +137,19 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
 
                     @Override
                     public WebMarkupContainer getPanel(final String panelId) {
-                        return new PlainSchemas(
+                        return new PlainSchemasMemberships(
                                 panelId,
                                 membershipSchemas.get(membershipTO.getGroupKey()),
-                                new ListModel<>(getAttrsFromTO(membershipTO)));
+                                new LoadableDetachableModel<AttributableTO>() { //
SYNCOPE-1439
+
+                            private static final long serialVersionUID = 526768546610546553L;
+
+                            @Override
+                            protected AttributableTO load() {
+                                return membershipTO;
+                            }
+
+                        });
                     }
                 }), Model.of(-1)).setOutputMarkupId(true));
             }
@@ -377,15 +389,88 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
         return panel;
     }
 
-    public class PlainSchemas extends Schemas {
+    protected class PlainSchemasMemberships extends PlainSchemas<AttributableTO> {
+
+        private static final long serialVersionUID = 456754923340249215L;
+
+        public PlainSchemasMemberships(
+                final String id,
+                final Map<String, PlainSchemaTO> schemas,
+                final IModel<AttributableTO> attributableTO) {
+
+            super(id, schemas, attributableTO);
+
+            add(new ListView<AttrTO>("schemas",
+                    new ListModel<AttrTO>(new ArrayList<AttrTO>(
+                            attributableTO.getObject().getPlainAttrs().stream().sorted(attrComparator).
+                                    collect(Collectors.toList())))) {
+
+                private static final long serialVersionUID = 5306618783986001008L;
+
+                @Override
+                @SuppressWarnings({ "unchecked", "rawtypes" })
+                protected void populateItem(final ListItem<AttrTO> item) {
+                    AttrTO attrTO = item.getModelObject();
+
+                    AbstractFieldPanel<?> panel = getFieldPanel(schemas.get(attrTO.getSchema()));
+                    if (mode == AjaxWizard.Mode.TEMPLATE
+                            || !schemas.get(attrTO.getSchema()).isMultivalue()) {
+
+                        FieldPanel.class.cast(panel).setNewModel(new Model() {
+
+                            private static final long serialVersionUID = -4214654722524358000L;
+
+                            @Override
+                            public Serializable getObject() {
+                                return (!attributableTO.getObject().getPlainAttr(attrTO.getSchema()).
+                                        get().getValues().isEmpty())
+                                                ? attributableTO.getObject().getPlainAttr(attrTO.getSchema()).
+                                                        get().getValues().get(0)
+                                                : null;
+                            }
+
+                            @Override
+                            public void setObject(final Serializable object) {
+                                attributableTO.getObject().getPlainAttr(attrTO.getSchema()).get().getValues().clear();
+                                if (object != null) {
+                                    attributableTO.getObject().getPlainAttr(attrTO.getSchema()).
+                                            get().getValues().add(object.toString());
+                                }
+                            }
+                        });
+                    } else {
+                        panel = new MultiFieldPanel.Builder<>(new ListModel<String>()
{
+
+                            private static final long serialVersionUID = -1765231556272935141L;
+
+                            @Override
+                            public List<String> getObject() {
+                                return attributableTO.getObject().getPlainAttr(attrTO.getSchema()).get().getValues();
+                            }
+                        }).build("panel",
+                                attrTO.getSchema(),
+                                FieldPanel.class.cast(panel));
+                        // SYNCOPE-1215 the entire multifield panel must be readonly, not
only its field
+                        ((MultiFieldPanel) panel).setReadOnly(schemas.get(attrTO.getSchema()).isReadonly());
+                    }
+                    item.add(panel);
+
+                    setExternalAction(attrTO, panel);
+                }
+            });
+        }
+    }
+
+    protected class PlainSchemasOwn extends PlainSchemas<List<AttrTO>> {
 
         private static final long serialVersionUID = -4730563859116024676L;
 
-        public PlainSchemas(
+        public PlainSchemasOwn(
                 final String id,
                 final Map<String, PlainSchemaTO> schemas,
-                final IModel<List<Attr>> attrTOs) {
-            super(id);
+                final IModel<List<AttrTO>> attrTOs) {
+
+            super(id, schemas, attrTOs);
 
             add(new ListView<Attr>("schemas", attrTOs) {
 
@@ -399,6 +484,7 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
                     AbstractFieldPanel<?> panel = getFieldPanel(schemas.get(attrTO.getSchema()));
                     if (mode == AjaxWizard.Mode.TEMPLATE
                             || !schemas.get(attrTO.getSchema()).isMultivalue()) {
+
                         FieldPanel.class.cast(panel).setNewModel(attrTO.getValues());
                     } else {
                         panel = new MultiFieldPanel.Builder<>(
@@ -411,24 +497,42 @@ public class PlainAttrs extends AbstractAttrs<PlainSchemaTO> {
                     }
                     item.add(panel);
 
-                    Optional<Attr> prevAttr = previousObject == null
-                            ? Optional.empty()
-                            : previousObject.getPlainAttr(attrTO.getSchema());
-                    if (previousObject != null
-                            && ((!prevAttr.isPresent() && attrTO.getValues().stream().anyMatch(StringUtils::isNotBlank))
-                            || (prevAttr.isPresent() && !ListUtils.isEqualList(
-                            prevAttr.get().getValues().stream().
-                                    filter(StringUtils::isNotBlank).collect(Collectors.toList()),
-                            attrTO.getValues().stream().
-                                    filter(StringUtils::isNotBlank).collect(Collectors.toList())))))
{
-
-                        List<String> oldValues = prevAttr.isPresent()
-                                ? prevAttr.get().getValues()
-                                : Collections.<String>emptyList();
-                        panel.showExternAction(new LabelInfo("externalAction", oldValues));
-                    }
+                    setExternalAction(attrTO, panel);
                 }
             });
         }
     }
+
+    protected abstract class PlainSchemas<T> extends Schemas {
+
+        private static final long serialVersionUID = 8315035592714180404L;
+
+        public PlainSchemas(
+                final String id,
+                final Map<String, PlainSchemaTO> schemas,
+                final IModel<T> attrTOs) {
+
+            super(id);
+        }
+
+        protected void setExternalAction(final AttrTO attrTO, final AbstractFieldPanel<?>
panel) {
+            Optional<AttrTO> prevAttr = previousObject == null
+                    ? Optional.empty()
+                    : previousObject.getPlainAttr(attrTO.getSchema());
+            if (previousObject != null
+                    && ((!prevAttr.isPresent() && attrTO.getValues().stream().anyMatch(StringUtils::isNotBlank))
+                    || (prevAttr.isPresent() && !ListUtils.isEqualList(
+                    prevAttr.get().getValues().stream().
+                            filter(StringUtils::isNotBlank).collect(Collectors.toList()),
+                    attrTO.getValues().stream().
+                            filter(StringUtils::isNotBlank).collect(Collectors.toList())))))
{
+
+                List<String> oldValues = prevAttr.isPresent()
+                        ? prevAttr.get().getValues()
+                        : Collections.<String>emptyList();
+                panel.showExternAction(new LabelInfo("externalAction", oldValues));
+            }
+        }
+    }
+
 }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
index 6e18a45..691ec4e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/UsersITCase.java
@@ -58,6 +58,10 @@ public class UsersITCase extends AbstractConsoleITCase {
                 "body:content:body:container:content:tabbedPanel:panel:accordionPanel:tabs:0:body:content:"
                 + "searchFormContainer:search:multiValueContainer:innerForm:content:view:0:panel:container:value:"
                 + "textField", TextField.class);
+        TESTER.assertComponent(
+                "body:content:body:container:content:tabbedPanel:panel:accordionPanel:tabs:0:body:content:"
+                + "searchFormContainer:search:multiValueContainer:innerForm:content:view:1:panel:container:value:"
+                + "textField", TextField.class);
     }
 
     @Test
@@ -323,6 +327,215 @@ public class UsersITCase extends AbstractConsoleITCase {
     }
 
     @Test
+    public void editUserMemberships() {
+        TESTER.clickLink("body:realmsLI:realms");
+        TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:btn", Constants.ON_CLICK);
+        TESTER.executeAjaxEvent("body:content:realmChoicePanel:container:realms:dropdown-menu:buttons:2:button",
+                Constants.ON_CLICK);
+
+        TESTER.clickLink("body:content:body:container:content:tabbedPanel:tabs-container:tabs:1:link");
+
+        Component component = findComponentByProp("username", CONTAINER
+                + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable",
"rossini");
+        assertNotNull(component);
+
+        // click on "edit"
+        TESTER.executeAjaxEvent(component.getPageRelativePath(), Constants.ON_CLICK);
+        TESTER.clickLink(TAB_PANEL + "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
+                + "actions:actions:actionRepeater:0:action:action");
+
+        FormTester formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+        formTester.submit("buttons:next");
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+        formTester.submit("buttons:next");
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+
+        // add "additional" group in order to show membership attributes
+        formTester.setValue("view:groupsContainer:groups:paletteField:recorder", "additional,root,otherchild");
+        TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form:buttons:next",
+                Constants.ON_CLICK);
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+
+        // open membership attributes accordion
+        TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:title",
+                Constants.ON_CLICK);
+
+        // edit multivalue text field, set 2 elements in total
+        TESTER.assertComponent(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:"
+                + "body:content:schemas:5:panel:multiValueContainer:innerForm:content:view:0:panel:field",
+                TextField.class);
+        formTester.setValue("view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:body:content:"
+                + "schemas:5:panel:multiValueContainer:innerForm:content:view:0:panel:field",
"2019-03-05");
+
+        TESTER.clickLink(TESTER.getComponentFromLastRenderedPage(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:"
+                + "body:content:schemas:5:panel:multiValueContainer:innerForm:content:view:0:panelPlus:add"));
+
+        TESTER.assertComponent(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:"
+                + "body:content:schemas:5:panel:multiValueContainer:innerForm:content:view:1:panel:field",
+                TextField.class);
+        formTester.setValue("view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:body:content:"
+                + "schemas:5:panel:multiValueContainer:innerForm:content:view:1:panel:field",
"2019-03-06");
+
+        TESTER.clickLink(TESTER.getComponentFromLastRenderedPage(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:"
+                + "body:content:schemas:5:panel:multiValueContainer:innerForm:content:view:1:panelPlus:add"));
+
+        formTester.submit("buttons:next");
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+        formTester.submit("buttons:finish");
+
+        TESTER.assertInfoMessages("Operation executed successfully");
+        TESTER.cleanupFeedbackMessages();
+
+        TESTER.assertComponent(TAB_PANEL
+                + "outerObjectsRepeater:0:outer:form:content:customResultBody:resources:firstLevelContainer:first:"
+                + "container:content:group:beans:0:fields:1:field", Label.class);
+
+        TESTER.clickLink(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:action:actionRepeater:0:action:action");
+
+        // reopen form and go to Plain Attributes page...
+        component = findComponentByProp("username", CONTAINER
+                + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable",
"rossini");
+        assertNotNull(component);
+
+        TESTER.executeAjaxEvent(component.getPageRelativePath(), Constants.ON_CLICK);
+        TESTER.clickLink(TAB_PANEL + "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
+                + "actions:actions:actionRepeater:0:action:action");
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+        formTester.submit("buttons:next");
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+        formTester.submit("buttons:next");
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+
+        // add "additional" group in order to show membership attributes
+        formTester.setValue("view:groupsContainer:groups:paletteField:recorder", "additional,root,otherchild");
+        TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form:buttons:next",
+                Constants.ON_CLICK);
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+
+        // open membership attributes accordion
+        TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:title",
+                Constants.ON_CLICK);
+
+        // ... check multivalue field values has been saved
+        TESTER.assertComponent(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:"
+                + "body:content:schemas:5:panel:multiValueContainer:innerForm:content:view:0:panel:field",
+                TextField.class);
+
+        TESTER.assertComponent(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:"
+                + "body:content:schemas:5:panel:multiValueContainer:innerForm:content:view:1:panel:field",
+                TextField.class);
+
+        Calendar cal = Calendar.getInstance();
+        cal.set(2019, Calendar.MARCH, 5, 0, 0, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+        Calendar cal2 = Calendar.getInstance();
+        cal2.set(2019, Calendar.MARCH, 6, 0, 0, 0);
+        cal2.set(Calendar.MILLISECOND, 0);
+        TESTER.assertModelValue(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:body:content:"
+                + "schemas:5:panel:multiValueContainer:innerForm:content:view:0:panel:field",
cal.getTime());
+        TESTER.assertModelValue(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:body:content:"
+                + "schemas:5:panel:multiValueContainer:innerForm:content:view:1:panel:field",
cal2.getTime());
+
+        // ... remove all values from multivalue field
+        TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:body:"
+                + "content:schemas:5:panel:multiValueContainer:innerForm:content:view:1:drop",
+                Constants.ON_CLICK);
+        TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:body:"
+                + "content:schemas:5:panel:multiValueContainer:innerForm:content:view:0:drop",
+                Constants.ON_CLICK);
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+        formTester.submit("buttons:finish");
+
+        TESTER.assertInfoMessages("Operation executed successfully");
+        TESTER.cleanupFeedbackMessages();
+
+        TESTER.assertComponent(TAB_PANEL
+                + "outerObjectsRepeater:0:outer:form:content:customResultBody:resources:firstLevelContainer:first:"
+                + "container:content:group:beans:0:fields:1:field", Label.class);
+
+        TESTER.clickLink(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:action:actionRepeater:0:action:action");
+
+        // reopen form and go to Plain Attributes page...
+        component = findComponentByProp("username", CONTAINER
+                + ":searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable",
"rossini");
+        assertNotNull(component);
+
+        TESTER.executeAjaxEvent(component.getPageRelativePath(), Constants.ON_CLICK);
+        TESTER.clickLink(TAB_PANEL + "outerObjectsRepeater:1:outer:container:content:togglePanelContainer:container:"
+                + "actions:actions:actionRepeater:0:action:action");
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+        formTester.submit("buttons:next");
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+        formTester.submit("buttons:next");
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+
+        // add "additional" group in order to show membership attributes
+        formTester.setValue("view:groupsContainer:groups:paletteField:recorder", "additional,root,otherchild");
+        TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form:buttons:next",
+                Constants.ON_CLICK);
+
+        formTester = TESTER.newFormTester(TAB_PANEL + "outerObjectsRepeater:0:outer:form:content:form");
+        assertNotNull(formTester);
+
+        // open membership attributes accordion
+        TESTER.executeAjaxEvent(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:title",
+                Constants.ON_CLICK);
+
+        // ... check multivalue field is now empty
+        TESTER.assertModelValue(TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:body:content:"
+                + "schemas:5:panel:multiValueContainer:innerForm:content:view:0:panel:field",
null);
+        component = findComponentByProp("syncope-path", TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:body:"
+                + "content:schemas:5:panel:multiValueContainer:innerForm",
+                TAB_PANEL + "outerObjectsRepeater:0:"
+                + "outer:form:content:form:view:membershipsPlainSchemas:0:membershipPlainSchemas:tabs:0:body:"
+                + "content:schemas:5:panel:multiValueContainer:innerForm:content:view:1:panel:field");
+        assertNull(component);
+
+        // close the wizard
+        formTester.submit("buttons:cancel");
+    }
+
+    @Test
     public void checkDeleteUsrLink() {
         TESTER.clickLink("body:realmsLI:realms");
         TESTER.clickLink("body:content:body:container:content:tabbedPanel:tabs-container:tabs:1:link");


Mime
View raw message