syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fmarte...@apache.org
Subject syncope git commit: [SYNCOPE-745] provides integration tests for report and provisions - still missing report download feature
Date Thu, 05 May 2016 10:51:58 GMT
Repository: syncope
Updated Branches:
  refs/heads/master 5472a323d -> 9e9bda9f0


[SYNCOPE-745] provides integration tests for report and provisions - still missing report download feature


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/9e9bda9f
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/9e9bda9f
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/9e9bda9f

Branch: refs/heads/master
Commit: 9e9bda9f03f2867c47ab68816d52c3fef7e325bc
Parents: 5472a32
Author: fmartelli <fabio.martelli@gmail.com>
Authored: Thu May 5 12:51:39 2016 +0200
Committer: fmartelli <fabio.martelli@gmail.com>
Committed: Thu May 5 12:51:39 2016 +0200

----------------------------------------------------------------------
 .../client/console/panels/ListViewPanel.java    |   6 +-
 .../console/reports/ExportTogglePanel.java      | 113 ++++++++
 .../console/reports/ReportDirectoryPanel.java   |   3 -
 .../reports/ReportletDirectoryPanel.java        |   3 +
 .../client/console/rest/ReportRestClient.java   |  27 ++
 .../console/tasks/ExecutionsDirectoryPanel.java |  17 ++
 .../ajax/form/AbstractAjaxDownloadBehavior.java |  49 ++++
 .../markup/html/form/SelectChoiceRenderer.java  |   2 +-
 .../console/wizards/AjaxWizardMgtButtonBar.java |   1 -
 .../resources/ProvisionWizardBuilder.java       |   5 +-
 .../wizards/resources/ResourceMappingPanel.java |   2 +
 .../console/reports/ExportTogglePanel.html      |  46 ++++
 .../markup/html/form/ActionLinksPanel.html      |   2 +-
 .../syncope/fit/console/ReportsITCase.java      | 257 +++++++++++++++++++
 .../syncope/fit/console/TopologyITCase.java     | 139 +++++++++-
 15 files changed, 659 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
index e15b151..e5fa626 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ListViewPanel.java
@@ -24,6 +24,7 @@ import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import org.apache.commons.collections4.IteratorUtils;
 import org.apache.commons.collections4.Predicate;
@@ -123,7 +124,8 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
         groupSelector = new CheckGroupSelector("groupselector", checkGroup);
         addInnerObject(groupSelector.setOutputMarkupId(true)
                 .setOutputMarkupPlaceholderTag(true)
-                .setVisible(this.check.getObject() == CheckAvailability.AVAILABLE));
+                .setVisible(this.check.getObject() == CheckAvailability.AVAILABLE)
+                .setEnabled(this.check.getObject() == CheckAvailability.AVAILABLE));
 
         final List<String> toBeIncluded;
         if (includes == null || includes.isEmpty()) {
@@ -220,7 +222,7 @@ public abstract class ListViewPanel<T extends Serializable> extends WizardMgtPan
 
         private static final long serialVersionUID = -3643771352897992172L;
 
-        private IModel<? extends Collection<T>> model = new Model<>();
+        private IModel<? extends Collection<T>> model = Model.of(Collections.<T>emptyList());
 
         private final List<String> includes = new ArrayList<>();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/java/org/apache/syncope/client/console/reports/ExportTogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/reports/ExportTogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/reports/ExportTogglePanel.java
new file mode 100644
index 0000000..0e5f631
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/reports/ExportTogglePanel.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.reports;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.HttpResourceStream;
+import org.apache.syncope.client.console.panels.TogglePanel;
+import org.apache.syncope.client.console.rest.ReportRestClient;
+import org.apache.syncope.client.console.wicket.ajax.form.AbstractAjaxDownloadBehavior;
+import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.common.lib.types.ReportExecExportFormat;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.util.resource.IResourceStream;
+
+public class ExportTogglePanel extends TogglePanel<Serializable> {
+
+    private static final long serialVersionUID = -3195479265440591519L;
+
+    private String execution;
+
+    private IModel<ReportExecExportFormat> model = Model.of(ReportExecExportFormat.CSV);
+
+    public ExportTogglePanel(final String id) {
+        super(id);
+
+        final AjaxDropDownChoicePanel<ReportExecExportFormat> format = new AjaxDropDownChoicePanel<>(
+                "format",
+                "format",
+                model,
+                false);
+
+        format.setChoices(Arrays.asList(ReportExecExportFormat.values())).setOutputMarkupId(true);
+
+        final AjaxExportDownloadBehavior downloadBehavior = new AjaxExportDownloadBehavior();
+        format.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+
+            private static final long serialVersionUID = -1107858522700306810L;
+
+            @Override
+            protected void onUpdate(final AjaxRequestTarget target) {
+                try {
+                    LOG.info("Downloding report execution {} [{}]", execution, format.getModelObject());
+                    downloadBehavior.setExportFormat(format.getModelObject()).initiate(target);
+                    toggle(target, false);
+                } catch (Exception e) {
+                    error(getString(Constants.ERROR) + ":" + e.getMessage());
+                    SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
+                }
+            }
+        }).add(downloadBehavior);
+
+        addInnerObject(format.hideLabel());
+    }
+
+    public void setExecution(final String execution) {
+        this.execution = execution;
+    }
+
+    private class AjaxExportDownloadBehavior extends AbstractAjaxDownloadBehavior {
+
+        private static final long serialVersionUID = 3109256773218160485L;
+
+        private ReportExecExportFormat exportFormat;
+
+        private HttpResourceStream stream;
+
+        public AjaxExportDownloadBehavior setExportFormat(final ReportExecExportFormat exportFormat) {
+            this.exportFormat = exportFormat;
+            return this;
+        }
+
+        private void createResourceStream() {
+            if (stream == null) {
+                stream = new HttpResourceStream(new ReportRestClient().exportExecutionResult(execution, exportFormat));
+            }
+        }
+
+        @Override
+        protected String getFileName() {
+            createResourceStream();
+            return stream == null ? null : stream.getFilename();
+        }
+
+        @Override
+        protected IResourceStream getResourceStream() {
+            createResourceStream();
+            return stream;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java
index cb5336b..8309a33 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportDirectoryPanel.java
@@ -37,7 +37,6 @@ import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BooleanPropertyColumn;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
@@ -66,8 +65,6 @@ public abstract class ReportDirectoryPanel
 
     private static final long serialVersionUID = 4984337552918213290L;
 
-    private final BaseModal<ReportTO> reportletModal = new BaseModal<ReportTO>("outer");
-
     private final ReportStartAtTogglePanel startAt;
 
     protected ReportDirectoryPanel(final MultilevelPanel multiLevelPanelRef, final PageReference pageRef) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
index 15f754a..bc761a3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
@@ -88,6 +88,9 @@ public class ReportletDirectoryPanel extends DirectoryPanel<
     protected ReportletDirectoryPanel(
             final BaseModal<ReportTO> baseModal, final String report, final PageReference pageRef) {
         super(BaseModal.CONTENT_ID, pageRef, false);
+
+        disableCheckBoxes();
+
         this.baseModal = baseModal;
         this.report = report;
         this.restClient = new ReportRestClient();

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
index 30e2037..a0ccfec 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
@@ -18,13 +18,18 @@
  */
 package org.apache.syncope.client.console.rest;
 
+import static org.apache.syncope.client.console.rest.BaseRestClient.getService;
+
 import java.io.InputStream;
 import java.util.Date;
 import java.util.List;
+import javax.ws.rs.NotSupportedException;
 import javax.ws.rs.core.Response;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.to.ReportTO;
 import org.apache.syncope.common.lib.to.ReportTemplateTO;
@@ -133,4 +138,26 @@ public class ReportRestClient extends BaseRestClient
         getService(ReportTemplateService.class).setFormat(
                 key, format, IOUtils.toInputStream(content, SyncopeConstants.DEFAULT_CHARSET));
     }
+
+    public BulkActionResult bulkAction(final BulkAction action) {
+        BulkActionResult result = new BulkActionResult();
+
+        switch (action.getType()) {
+            case DELETE:
+                for (String target : action.getTargets()) {
+                    delete(target);
+                    result.getResults().put(target, BulkActionResult.Status.SUCCESS);
+                }
+                break;
+            case EXECUTE:
+                for (String target : action.getTargets()) {
+                    startExecution(target, new Date());
+                    result.getResults().put(target, BulkActionResult.Status.SUCCESS);
+                }
+                break;
+            default:
+                throw new NotSupportedException(action.getType().name());
+        }
+        return result;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
index 10545f1..872faf0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
@@ -32,6 +32,7 @@ import org.apache.syncope.client.console.panels.DirectoryPanel;
 import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
 import org.apache.syncope.client.console.panels.MultilevelPanel;
 import org.apache.syncope.client.console.panels.MultilevelPanel.SecondLevel;
+import org.apache.syncope.client.console.reports.ExportTogglePanel;
 import org.apache.syncope.client.console.rest.ExecutionRestClient;
 import org.apache.syncope.client.console.tasks.ExecutionsDirectoryPanel.ExecProvider;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
@@ -57,6 +58,8 @@ public abstract class ExecutionsDirectoryPanel
 
     private static final long serialVersionUID = 2039393934721149162L;
 
+    private final ExportTogglePanel export;
+
     private final BaseModal<?> baseModal;
 
     private final MultilevelPanel multiLevelPanelRef;
@@ -78,6 +81,10 @@ public abstract class ExecutionsDirectoryPanel
             final ExecutionRestClient executionRestClient,
             final PageReference pageRef) {
         super(MultilevelPanel.FIRST_LEVEL_ID, pageRef, false);
+
+        this.export = new ExportTogglePanel("outer");
+        addOuterObject(this.export);
+
         this.baseModal = baseModal;
         this.multiLevelPanelRef = multiLevelPanelRef;
         restClient = executionRestClient;
@@ -132,6 +139,16 @@ public abstract class ExecutionsDirectoryPanel
 
                             @Override
                             public void onClick(final AjaxRequestTarget target, final ExecTO ignore) {
+                                export.setExecution(model.getObject().getKey());
+                                export.toggle(target, true);
+                            }
+                        }, ActionLink.ActionType.EXPORT, StandardEntitlement.REPORT_READ).
+                        add(new ActionLink<ExecTO>() {
+
+                            private static final long serialVersionUID = -3722207913631435501L;
+
+                            @Override
+                            public void onClick(final AjaxRequestTarget target, final ExecTO ignore) {
                                 try {
                                     restClient.deleteExecution(taskExecutionTO.getKey());
                                     info(getString(Constants.OPERATION_SUCCEEDED));

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/form/AbstractAjaxDownloadBehavior.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/form/AbstractAjaxDownloadBehavior.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/form/AbstractAjaxDownloadBehavior.java
new file mode 100644
index 0000000..b6db880
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/ajax/form/AbstractAjaxDownloadBehavior.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.wicket.ajax.form;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.behavior.AbstractAjaxBehavior;
+import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
+import org.apache.wicket.util.resource.IResourceStream;
+
+public abstract class AbstractAjaxDownloadBehavior extends AbstractAjaxBehavior {
+
+    private static final long serialVersionUID = 6833760760338614245L;
+
+    /**
+     * Call this method to initiate the download.
+     *
+     * @param target request target.
+     */
+    public void initiate(final AjaxRequestTarget target) {
+        CharSequence url = getCallbackUrl();
+        target.appendJavaScript("window.location.href='" + url + "'");
+    }
+
+    @Override
+    public void onRequest() {
+        getComponent().getRequestCycle().scheduleRequestHandlerAfterCurrent(
+                new ResourceStreamRequestHandler(getResourceStream(), getFileName()));
+    }
+
+    protected abstract String getFileName();
+
+    protected abstract IResourceStream getResourceStream();
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SelectChoiceRenderer.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SelectChoiceRenderer.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SelectChoiceRenderer.java
index d4a7644..82e5354 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SelectChoiceRenderer.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SelectChoiceRenderer.java
@@ -48,7 +48,7 @@ public class SelectChoiceRenderer<T> implements IChoiceRenderer<T> {
 
             @Override
             public boolean evaluate(final T object) {
-                return id.equals(getIdValue(object, 0));
+                return id != null && id.equals(getIdValue(object, 0));
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardMgtButtonBar.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardMgtButtonBar.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardMgtButtonBar.java
index 6a58e46..157fea7 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardMgtButtonBar.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizardMgtButtonBar.java
@@ -76,7 +76,6 @@ public class AjaxWizardMgtButtonBar<T extends Serializable> extends WizardButton
             @Override
             protected void onSubmit(final AjaxRequestTarget target) {
                 target.add(findParent(Wizard.class));
-
                 button.onSubmit();
             }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
index e8b4947..68f8c92 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ProvisionWizardBuilder.java
@@ -238,7 +238,7 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> imple
     public void setEventSink(final IEventSink eventSink) {
         this.eventSink = eventSink;
     }
-    
+
     @Override
     protected WizardModel buildModelSteps(final ProvisionTO modelObject, final WizardModel wizardModel) {
         wizardModel.add(new ObjectType(modelObject));
@@ -250,6 +250,9 @@ public class ProvisionWizardBuilder extends AjaxWizardBuilder<ProvisionTO> imple
 
     @Override
     protected Serializable onApplyInternal(final ProvisionTO modelObject) {
+        if (modelObject.getKey() == null) {
+            this.resourceTO.getProvisions().add(modelObject);
+        }
         return modelObject;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
index 5733f48..1e37df3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
@@ -651,6 +651,8 @@ public class ResourceMappingPanel extends Panel {
             res.addAll(IntMappingType.getAttributeTypes(kind));
         }
 
+        Collections.sort(res);
+
         return res;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/resources/org/apache/syncope/client/console/reports/ExportTogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/reports/ExportTogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/reports/ExportTogglePanel.html
new file mode 100644
index 0000000..da3c7f8
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/reports/ExportTogglePanel.html
@@ -0,0 +1,46 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:head>
+    <style type="text/css">
+      div#startAt {
+        background-color: rgba(98, 98, 98, 0.98) !important;
+        color: #CCC;
+        right: 5px !important;
+        top: 100px !important;
+        min-width: 300px;
+        min-height: 130px !important;
+        z-index: 6000 !important;
+      }
+
+      div#startAtContainer {
+        padding: 15px;
+      }
+
+      div#startAtContainer input {
+        background-color: rgba(200, 200, 200, 0.60) !important;
+      }
+    </style>
+  </wicket:head>
+  <wicket:extend>
+    <div id="startAtContainer" class="form-group">
+      <span wicket:id="format"></span>
+    </div>
+  </wicket:extend>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
index 01afd7c..c8d2e96 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionLinksPanel.html
@@ -181,7 +181,7 @@ under the License.
     </wicket:fragment>
 
     <wicket:fragment wicket:id="fragmentExport">
-      <a href="#" wicket:id="exportLink" class="btn"><img id="actionLink" src="img/actions/export.png" alt="export icon" title="Export"/></a>
+      <a href="#" wicket:id="exportLink" class="btn"><i class="fa fa-floppy-o" alt="export icon" title="Export"></i></a>
     </wicket:fragment>
 
     <wicket:fragment wicket:id="fragmentSuspend">

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ReportsITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ReportsITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ReportsITCase.java
new file mode 100644
index 0000000..1a5407c
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/ReportsITCase.java
@@ -0,0 +1,257 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.console;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import org.apache.syncope.client.console.pages.Reports;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.util.tester.FormTester;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ReportsITCase extends AbstractConsoleITCase {
+
+    private void createReport(final String name) {
+        wicketTester.clickLink("body:content:tabbedPanel:panel:firstLevelContainer:first:container:content:add");
+
+        wicketTester.assertComponent(
+                "body:content:tabbedPanel:panel:firstLevelContainer:first:outerObjectsRepeater:0:outer", Modal.class);
+
+        FormTester formTester = wicketTester.newFormTester(
+                "body:content:tabbedPanel:panel:firstLevelContainer:first:outerObjectsRepeater:0:outer:form");
+        formTester.setValue("content:form:view:name:textField", name);
+        formTester.setValue("content:form:view:template:dropDownChoiceField", "0");
+        formTester.submit("content:form:buttons:next");
+
+        wicketTester.assertComponent("body:content:tabbedPanel:panel:firstLevelContainer:first:outerObjectsRepeater"
+                + ":0:outer:form:content:form:view:schedule:seconds:textField", TextField.class);
+
+        formTester = wicketTester.newFormTester(
+                "body:content:tabbedPanel:panel:firstLevelContainer:first:outerObjectsRepeater:0:outer:form");
+        formTester.submit("content:form:buttons:finish");
+
+        wicketTester.assertInfoMessages("Operation executed successfully");
+        wicketTester.cleanupFeedbackMessages();
+
+        wicketTester.clickLink("body:reportsLI:reports");
+    }
+
+    private void delete(final String name) {
+        wicketTester.clickLink("body:reportsLI:reports");
+
+        Component result = findComponentByProp(
+                "name", "body:content:tabbedPanel:panel:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", name);
+
+        assertNotNull(result);
+
+        wicketTester.getRequest().addParameter("confirm", "true");
+        wicketTester.clickLink(
+                wicketTester.getComponentFromLastRenderedPage(
+                        result.getPageRelativePath() + ":cells:10:cell:panelDelete:deleteLink"));
+
+        wicketTester.executeAjaxEvent(wicketTester.getComponentFromLastRenderedPage(
+                result.getPageRelativePath() + ":cells:10:cell:panelDelete:deleteLink"), "onclick");
+
+        wicketTester.assertInfoMessages("Operation executed successfully");
+        wicketTester.cleanupFeedbackMessages();
+
+        assertNull(findComponentByProp(
+                "name", "body:content:tabbedPanel:panel:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "deleteReport"));
+    }
+
+    private void deleteReportlet(final String report, final String reportlet) {
+        wicketTester.clickLink("body:reportsLI:reports");
+
+        Component result = findComponentByProp(
+                "name", "body:content:tabbedPanel:panel:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", report);
+
+        assertNotNull(result);
+
+        wicketTester.clickLink(result.getPageRelativePath() + ":cells:10:cell:panelCompose:composeLink");
+
+        result = findComponentByProp("name", "body:content:tabbedPanel:panel:firstLevelContainer:first:"
+                + "outerObjectsRepeater:0:outer:form:content:container:content:searchContainer:resultTable:tablePanel:"
+                + "groupForm:checkgroup:dataTable", reportlet);
+
+        assertNotNull(result);
+
+        wicketTester.getRequest().addParameter("confirm", "true");
+        wicketTester.clickLink(wicketTester.getComponentFromLastRenderedPage(
+                result.getPageRelativePath() + ":cells:3:cell:panelDelete:deleteLink"));
+
+        wicketTester.assertInfoMessages("Operation executed successfully");
+        wicketTester.cleanupFeedbackMessages();
+
+        assertNull(findComponentByProp("name", "body:content:tabbedPanel:panel:firstLevelContainer:first:"
+                + "outerObjectsRepeater:0:outer:form:content:container:content:searchContainer:resultTable:tablePanel:"
+                + "groupForm:checkgroup:dataTable", reportlet));
+    }
+
+    @Before
+    public void login() {
+        doLogin(ADMIN_UNAME, ADMIN_PWD);
+        wicketTester.clickLink("body:reportsLI:reports");
+        wicketTester.assertRenderedPage(Reports.class);
+    }
+
+    @Test
+    public void read() {
+        Component result = findComponentByProp(
+                "name", "body:content:tabbedPanel:panel:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "test");
+
+        assertNotNull(result);
+
+        wicketTester.clickLink(result.getPageRelativePath() + ":cells:10:cell:panelView:viewLink");
+
+        result = findComponentByProp("status", "body:content:tabbedPanel:panel:secondLevelContainer:second:executions:"
+                + "firstLevelContainer:first:container:content:searchContainer:resultTable:tablePanel:groupForm:"
+                + "checkgroup:dataTable", "SUCCESS");
+
+        assertNotNull(result);
+
+        wicketTester.clickLink(result.getPageRelativePath() + ":cells:6:cell:panelExport:exportLink");
+        wicketTester.assertComponent("body:content:tabbedPanel:panel:secondLevelContainer:second:executions:"
+                + "firstLevelContainer:first:outerObjectsRepeater:3:outer:container:content:togglePanelContainer:close",
+                AjaxLink.class);
+
+        wicketTester.clickLink(
+                "body:content:tabbedPanel:panel:secondLevelContainer:second:executions:firstLevelContainer:first:"
+                + "outerObjectsRepeater:3:outer:container:content:togglePanelContainer:close");
+
+        wicketTester.clickLink(result.getPageRelativePath() + ":cells:6:cell:panelView:viewLink");
+        wicketTester.clickLink(
+                "body:content:tabbedPanel:panel:secondLevelContainer:second:executions:secondLevelContainer:back");
+
+        wicketTester.clickLink("body:content:tabbedPanel:panel:secondLevelContainer:back");
+
+        assertNotNull(findComponentByProp(
+                "name", "body:content:tabbedPanel:panel:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "reconciliation"));
+    }
+
+    @Test
+    public void cloneReportlets() {
+        final String report = "test";
+        final String reportlet = "myClone";
+
+        Component result = findComponentByProp(
+                "name", "body:content:tabbedPanel:panel:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", report);
+
+        assertNotNull(result);
+
+        wicketTester.clickLink(result.getPageRelativePath() + ":cells:10:cell:panelCompose:composeLink");
+
+        result = findComponentByProp("name", "body:content:tabbedPanel:panel:firstLevelContainer:first:"
+                + "outerObjectsRepeater:0:outer:form:content:container:content:searchContainer:resultTable:tablePanel:"
+                + "groupForm:checkgroup:dataTable", "testUserReportlet");
+
+        assertNotNull(result);
+        wicketTester.clickLink(result.getPageRelativePath() + ":cells:3:cell:panelClone:cloneLink");
+
+        FormTester formTester = wicketTester.newFormTester("body:content:tabbedPanel:panel:firstLevelContainer:first:"
+                + "outerObjectsRepeater:0:outer:form:content:container:content:wizard:form");
+
+        formTester.setValue("view:name:textField", reportlet);
+        formTester.submit("buttons:finish");
+
+        wicketTester.assertInfoMessages("Operation executed successfully");
+        wicketTester.cleanupFeedbackMessages();
+
+        deleteReportlet(report, reportlet);
+
+        wicketTester.clickLink("body:content:tabbedPanel:panel:firstLevelContainer:first:outerObjectsRepeater:0:"
+                + "outer:form:content:container:content:exit");
+
+        wicketTester.assertRenderedPage(Reports.class);
+    }
+
+    @Test
+    public void createReportlets() {
+        final String report = "test";
+        final String reportlet = "myNewReportlet";
+
+        Component result = findComponentByProp(
+                "name", "body:content:tabbedPanel:panel:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", report);
+
+        assertNotNull(result);
+
+        wicketTester.clickLink(result.getPageRelativePath() + ":cells:10:cell:panelCompose:composeLink");
+
+        wicketTester.clickLink("body:content:tabbedPanel:panel:firstLevelContainer:first:outerObjectsRepeater:0:"
+                + "outer:form:content:container:content:add");
+
+        FormTester formTester = wicketTester.newFormTester("body:content:tabbedPanel:panel:firstLevelContainer:first:"
+                + "outerObjectsRepeater:0:outer:form:content:container:content:wizard:form");
+
+        formTester.setValue("view:name:textField", reportlet);
+        formTester.setValue("view:configuration:dropDownChoiceField", "1");
+        formTester.submit("buttons:next");
+
+        formTester = wicketTester.newFormTester("body:content:tabbedPanel:panel:firstLevelContainer:first:"
+                + "outerObjectsRepeater:0:outer:form:content:container:content:wizard:form");
+        formTester.submit("buttons:finish");
+
+        wicketTester.assertInfoMessages("Operation executed successfully");
+        wicketTester.cleanupFeedbackMessages();
+
+        deleteReportlet(report, reportlet);
+
+        wicketTester.clickLink("body:content:tabbedPanel:panel:firstLevelContainer:first:outerObjectsRepeater:0:"
+                + "outer:form:content:container:content:exit");
+
+        wicketTester.assertRenderedPage(Reports.class);
+    }
+
+    @Test
+    public void update() {
+        createReport("updateReport");
+        Component result = findComponentByProp(
+                "name", "body:content:tabbedPanel:panel:firstLevelContainer:first:container:"
+                + "content:searchContainer:resultTable:tablePanel:groupForm:checkgroup:dataTable", "updateReport");
+
+        wicketTester.clickLink(result.getPageRelativePath() + ":cells:10:cell:panelEdit:editLink");
+
+        FormTester formTester = wicketTester.newFormTester(
+                "body:content:tabbedPanel:panel:firstLevelContainer:first:outerObjectsRepeater:0:outer:form");
+        formTester.setValue("content:form:view:template:dropDownChoiceField", "1");
+
+        formTester = wicketTester.newFormTester(
+                "body:content:tabbedPanel:panel:firstLevelContainer:first:outerObjectsRepeater:0:outer:form");
+        formTester.submit("content:form:buttons:finish");
+
+        wicketTester.assertInfoMessages("Operation executed successfully");
+        wicketTester.cleanupFeedbackMessages();
+
+        delete("updateReport");
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/9e9bda9f/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
index 45375d6..05527bc 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/console/TopologyITCase.java
@@ -19,7 +19,10 @@
 package org.apache.syncope.fit.console;
 
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
+import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
+import java.util.UUID;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.wicket.markup.html.form.NonI18nPalette;
 import org.apache.wicket.Component;
@@ -89,20 +92,148 @@ public class TopologyITCase extends AbstractConsoleITCase {
 
         wicketTester.assertComponent("body:toggle:outerObjectsRepeater:2:outer:form:content:provision:"
                 + "container:content:wizard:form:view:mapping:mappingContainer:mappings:1", WebMarkupContainer.class);
-        
+
         wicketTester.executeAjaxEvent("body:toggle:outerObjectsRepeater:2:outer:form:content:provision:"
-                + "container:content:wizard:form:view:mapping:mappingContainer:mappings:1:transformers:icon", 
+                + "container:content:wizard:form:view:mapping:mappingContainer:mappings:1:transformers:icon",
                 Constants.ON_CLICK);
-        
+
         wicketTester.clickLink("body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:content:"
                 + "wizard:form:view:mapping:mappingContainer:mappings:0:transformers:alertsLink");
-        
+
         wicketTester.assertComponent("body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:"
                 + "content:wizard:form:view:mapping:transformersTogglePanel:container:content:togglePanelContainer:"
                 + "form:classes:paletteField", NonI18nPalette.class);
     }
 
     @Test
+    public void createNewResurceAndProvisionRules() {
+        final String res = UUID.randomUUID().toString();
+        wicketTester.clickLink("body:topologyLI:topology");
+
+        wicketTester.executeAjaxEvent(
+                "body:conns:0:conns:0:conn", Constants.ON_CLICK);
+        wicketTester.executeAjaxEvent(
+                "body:toggle:container:content:togglePanelContainer:container:actions:create", Constants.ON_CLICK);
+
+        FormTester formTester
+                = wicketTester.newFormTester("body:toggle:outerObjectsRepeater:0:outer:form:content:form");
+
+        formTester.setValue("view:container:key:textField", res);
+        formTester.submit("buttons:next");
+
+        formTester = wicketTester.newFormTester("body:toggle:outerObjectsRepeater:0:outer:form:content:form");
+        formTester.submit("buttons:next");
+
+        formTester = wicketTester.newFormTester("body:toggle:outerObjectsRepeater:0:outer:form:content:form");
+        formTester.submit("buttons:next");
+
+        // click on finish to create the external resource 
+        wicketTester.cleanupFeedbackMessages();
+        // ajax event required to retrieve AjaxRequestTarget (used into finish custom event)
+        wicketTester.executeAjaxEvent(
+                "body:toggle:outerObjectsRepeater:0:outer:form:content:form:buttons:finish", Constants.ON_CLICK);
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.cleanupFeedbackMessages();
+        wicketTester.clickLink("body:topologyLI:topology");
+
+        Component component = findComponentByProp("key", "body:resources", res);
+        assertNotNull(component);
+        wicketTester.executeAjaxEvent(component.getPageRelativePath() + ":res", Constants.ON_CLICK);
+        wicketTester.clickLink("body:toggle:container:content:togglePanelContainer:container:actions:provision");
+
+        wicketTester.clickLink("body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:content:add");
+
+        formTester = wicketTester.newFormTester(
+                "body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:content:wizard:form");
+
+        formTester.setValue("view:container:type:dropDownChoiceField", "0");
+        formTester.setValue("view:container:class", "__ACCOUNT__");
+        formTester.submit("buttons:next");
+        wicketTester.assertNoErrorMessage();
+        wicketTester.assertNoInfoMessage();
+
+        formTester = wicketTester.newFormTester(
+                "body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:content:wizard:form");
+        formTester.submit("buttons:next");
+        wicketTester.assertNoErrorMessage();
+        wicketTester.assertNoInfoMessage();
+
+        wicketTester.executeAjaxEvent("body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:"
+                + "content:wizard:form:view:mapping:mappingContainer:addMappingBtn", Constants.ON_CLICK);
+
+        formTester = wicketTester.newFormTester(
+                "body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:content:wizard:form");
+
+        formTester.setValue("view:mapping:mappingContainer:mappings:0:entities:dropDownChoiceField", "0");
+        wicketTester.executeAjaxEvent(
+                "body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:content:wizard:form"
+                + ":view:mapping:mappingContainer:mappings:0:entities:dropDownChoiceField", Constants.ON_CHANGE);
+
+        formTester.setValue("view:mapping:mappingContainer:mappings:0:intMappingTypes:dropDownChoiceField", "4");
+        wicketTester.executeAjaxEvent(
+                "body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:content:wizard:form"
+                + ":view:mapping:mappingContainer:mappings:0:intMappingTypes:dropDownChoiceField", Constants.ON_CHANGE);
+
+        formTester.setValue("view:mapping:mappingContainer:mappings:0:connObjectKey:checkboxField", "true");
+        wicketTester.executeAjaxEvent(
+                "body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:content:wizard:form"
+                + ":view:mapping:mappingContainer:mappings:0:connObjectKey:checkboxField", Constants.ON_CHANGE);
+
+        formTester.setValue("view:mapping:mappingContainer:mappings:0:entities:dropDownChoiceField", "0");
+        formTester.setValue("view:mapping:mappingContainer:mappings:0:intMappingTypes:dropDownChoiceField", "4");
+        formTester.setValue("view:mapping:mappingContainer:mappings:0:extAttrName:textField", "ID");
+        formTester.setValue("view:mapping:mappingContainer:mappings:0:connObjectKey:checkboxField", "true");
+
+        formTester.submit("buttons:next");
+        wicketTester.assertNoErrorMessage();
+        wicketTester.assertNoInfoMessage();
+
+        wicketTester.cleanupFeedbackMessages();
+        // ajax event required to retrieve AjaxRequestTarget (used into finish custom event)
+        wicketTester.executeAjaxEvent("body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:"
+                + "content:wizard:form:buttons:finish", Constants.ON_CLICK);
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.assertComponent(
+                "body:toggle:outerObjectsRepeater:2:outer:dialog:footer:inputs:0:submit", AjaxSubmitLink.class);
+
+        wicketTester.cleanupFeedbackMessages();
+        wicketTester.executeAjaxEvent(
+                "body:toggle:outerObjectsRepeater:2:outer:dialog:footer:inputs:0:submit", Constants.ON_CLICK);
+        wicketTester.assertInfoMessages("Operation executed successfully");
+
+        wicketTester.clickLink("body:toggle:container:content:togglePanelContainer:container:actions:provision");
+
+        wicketTester.clickLink("body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:"
+                + "content:group:beans:0:actions:panelMapping:mappingLink");
+
+        formTester = wicketTester.newFormTester(
+                "body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:content:wizard:form");
+        formTester.submit("buttons:next");
+
+        wicketTester.assertComponent("body:toggle:outerObjectsRepeater:2:outer:form:content:provision:"
+                + "container:content:wizard:form:view:mapping:mappingContainer:mappings:0", WebMarkupContainer.class);
+
+        wicketTester.executeAjaxEvent(
+                "body:toggle:outerObjectsRepeater:2:outer:form:content:provision:container:content:"
+                + "wizard:form:buttons:cancel", Constants.ON_CLICK);
+
+        wicketTester.clickLink("body:toggle:outerObjectsRepeater:2:outer:dialog:footer:buttons:0:button");
+
+        wicketTester.cleanupFeedbackMessages();
+        wicketTester.getRequest().addParameter("confirm", "true");
+        wicketTester.clickLink("body:toggle:container:content:togglePanelContainer:container:actions:delete");
+
+        wicketTester.assertInfoMessages("Operation executed successfully");
+        wicketTester.cleanupFeedbackMessages();
+
+        wicketTester.clickLink("body:topologyLI:topology");
+        component = findComponentByProp("key", "body:resources", res);
+        assertNull(component);
+    }
+
+    @Test
     public void executePullTask() {
         wicketTester.clickLink("body:topologyLI:topology");
 


Mime
View raw message