commit 4a974f5cde8d9e530bd05e154b36fec2d4d36023 Author: Trang Truong Thi Huyen Date: Tue Apr 21 09:52:50 2015 +0700 MGNLUI-3386: Fix comments to reasonable one. diff --git a/magnolia-ui-contentapp/src/test/java/info/magnolia/ui/contentapp/renderer/SelectionSensitiveActionRendererTest.java b/magnolia-ui-contentapp/src/test/java/info/magnolia/ui/contentapp/renderer/SelectionSensitiveActionRendererTest.java index 235dcbf..15c1bed 100644 --- a/magnolia-ui-contentapp/src/test/java/info/magnolia/ui/contentapp/renderer/SelectionSensitiveActionRendererTest.java +++ b/magnolia-ui-contentapp/src/test/java/info/magnolia/ui/contentapp/renderer/SelectionSensitiveActionRendererTest.java @@ -94,7 +94,7 @@ public class SelectionSensitiveActionRendererTest extends MgnlTestCase { View view = renderer.start(actionDefinition, actionListener); // WHEN - // valid change event send, availability ok + // applicable item change event is sent, should pass availability check chooseDialogEventBus.fireEvent(event); // THEN @@ -108,7 +108,7 @@ public class SelectionSensitiveActionRendererTest extends MgnlTestCase { View view = renderer.start(actionDefinition, actionListener); // WHEN - // valid change event send, availability ko + // applicable item change event is sent, shouldn't pass availability check chooseDialogEventBus.fireEvent(event); // THEN commit 561940b502e3373cbaa43c15ca8fe6ab8a47c387 Author: Trang Truong Thi Huyen Date: Mon Apr 6 14:54:41 2015 +0700 MGNLUI-3386: Add SelectionSensitiveActionRenderer to support abilability checker to chooseDialog action. diff --git a/magnolia-ui-contentapp/src/main/java/info/magnolia/ui/contentapp/ContentApp.java b/magnolia-ui-contentapp/src/main/java/info/magnolia/ui/contentapp/ContentApp.java index ace21da..0e99226 100644 --- a/magnolia-ui-contentapp/src/main/java/info/magnolia/ui/contentapp/ContentApp.java +++ b/magnolia-ui-contentapp/src/main/java/info/magnolia/ui/contentapp/ContentApp.java @@ -33,7 +33,6 @@ */ package info.magnolia.ui.contentapp; - import info.magnolia.objectfactory.ComponentProvider; import info.magnolia.ui.api.app.AppContext; import info.magnolia.ui.api.app.AppView; @@ -42,6 +41,9 @@ import info.magnolia.ui.api.context.UiContext; import info.magnolia.ui.contentapp.browser.BrowserSubAppDescriptor; import info.magnolia.ui.contentapp.choosedialog.ChooseDialogComponentProviderUtil; import info.magnolia.ui.contentapp.field.WorkbenchFieldDefinition; +import info.magnolia.ui.contentapp.renderer.SelectionSensitiveActionRenderer; +import info.magnolia.ui.dialog.actionarea.definition.ActionRendererDefinition; +import info.magnolia.ui.dialog.actionarea.definition.ConfiguredActionRendererDefinition; import info.magnolia.ui.dialog.choosedialog.ChooseDialogPresenter; import info.magnolia.ui.dialog.definition.ChooseDialogDefinition; import info.magnolia.ui.dialog.definition.ConfiguredChooseDialogDefinition; @@ -52,6 +54,8 @@ import info.magnolia.ui.vaadin.integration.contentconnector.ContentConnectorDefi import info.magnolia.ui.vaadin.integration.contentconnector.JcrContentConnectorDefinition; import info.magnolia.ui.workbench.definition.ConfiguredWorkbenchDefinition; +import java.util.Map; + import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; @@ -67,7 +71,6 @@ public class ContentApp extends BaseApp { private static final Logger log = LoggerFactory.getLogger(ContentApp.class); - private ComponentProvider componentProvider; private Cloner cloner = new Cloner(); private ChooseDialogPresenter presenter; @@ -83,6 +86,8 @@ public class ContentApp extends BaseApp { openChooseDialog(overlayLayer, null, selectedId, callback); } + public static final String COMMIT_CHOOSE_DIALOG_ACTION = "commit"; + @Override public void openChooseDialog(UiContext overlayLayer, String targetTreeRootPath, String selectedId, final ChooseDialogCallback callback) { @@ -94,6 +99,7 @@ public class ContentApp extends BaseApp { chooseDialogDefinition = new ConfiguredChooseDialogDefinition(); } chooseDialogDefinition = ensureChooseDialogField(chooseDialogDefinition, targetTreeRootPath); + chooseDialogDefinition = addAvailabilityActionRenderer(chooseDialogDefinition); // create chooseDialogComponentProvider and get new instance of presenter from there ComponentProvider chooseDialogComponentProvider = ChooseDialogComponentProviderUtil.createChooseDialogComponentProvider(overlayLayer, chooseDialogDefinition, componentProvider); @@ -106,6 +112,16 @@ public class ContentApp extends BaseApp { presenter.start(callback, chooseDialogDefinition, overlayLayer, selectedId); } + private ChooseDialogDefinition addAvailabilityActionRenderer(ChooseDialogDefinition chooseDialogDefinition) { + Map actionRenderers = chooseDialogDefinition.getActionArea().getActionRenderers(); + if (!actionRenderers.containsKey(COMMIT_CHOOSE_DIALOG_ACTION)) { + ConfiguredActionRendererDefinition actionRendererDef = new ConfiguredActionRendererDefinition(); + actionRendererDef.setRendererClass(SelectionSensitiveActionRenderer.class); + actionRenderers.put(COMMIT_CHOOSE_DIALOG_ACTION, actionRendererDef); + } + return chooseDialogDefinition; + } + private ChooseDialogDefinition ensureChooseDialogField(ChooseDialogDefinition definition, String targetTreeRootPath) { if (definition.getField() != null && definition.getContentConnector() != null) { diff --git a/magnolia-ui-contentapp/src/main/java/info/magnolia/ui/contentapp/renderer/SelectionSensitiveActionRenderer.java b/magnolia-ui-contentapp/src/main/java/info/magnolia/ui/contentapp/renderer/SelectionSensitiveActionRenderer.java new file mode 100644 index 0000000..33f5d6c --- /dev/null +++ b/magnolia-ui-contentapp/src/main/java/info/magnolia/ui/contentapp/renderer/SelectionSensitiveActionRenderer.java @@ -0,0 +1,92 @@ +/** + * This file Copyright (c) 2015 Magnolia International + * Ltd. (http://www.magnolia-cms.com). All rights reserved. + * + * + * This file is dual-licensed under both the Magnolia + * Network Agreement and the GNU General Public License. + * You may elect to use one or the other of these licenses. + * + * This file is distributed in the hope that it will be + * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT. + * Redistribution, except as permitted by whichever of the GPL + * or MNA you select, is prohibited. + * + * 1. For the GPL license (GPL), you can redistribute and/or + * modify this file under the terms of the GNU General + * Public License, Version 3, as published by the Free Software + * Foundation. You should have received a copy of the GNU + * General Public License, Version 3 along with this program; + * if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * 2. For the Magnolia Network Agreement (MNA), this file + * and the accompanying materials are made available under the + * terms of the MNA which accompanies this distribution, and + * is available at http://www.magnolia-cms.com/mna.html + * + * Any modifications to this file must keep this entire header + * intact. + * + */ +package info.magnolia.ui.contentapp.renderer; + +import info.magnolia.event.EventBus; +import info.magnolia.ui.api.action.ActionDefinition; +import info.magnolia.ui.api.availability.AvailabilityChecker; +import info.magnolia.ui.api.availability.AvailabilityDefinition; +import info.magnolia.ui.api.event.ChooseDialogEventBus; +import info.magnolia.ui.api.view.View; +import info.magnolia.ui.dialog.actionarea.ActionListener; +import info.magnolia.ui.dialog.actionarea.renderer.DefaultEditorActionRenderer; +import info.magnolia.ui.framework.overlay.ViewAdapter; +import info.magnolia.ui.workbench.event.SelectionChangedEvent; + +import java.util.Collections; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Named; + +import com.google.common.collect.Lists; +import com.vaadin.ui.Component; + +/** + * {@link info.magnolia.ui.dialog.actionarea.renderer.ActionRenderer} implementation that alters the 'enabled'-state of + * the underlying Vaadin view based on {@link AvailabilityChecker} decision made against a current selection provided + * by {@link SelectionChangedEvent} via {@link ChooseDialogEventBus}. + */ +public class SelectionSensitiveActionRenderer extends DefaultEditorActionRenderer { + + private final EventBus chooseDialogEventBus; + private final AvailabilityChecker availabilityChecker; + + @Inject + public SelectionSensitiveActionRenderer(@Named(ChooseDialogEventBus.NAME) EventBus chooseDialogEventBus, AvailabilityChecker availabilityChecker) { + this.chooseDialogEventBus = chooseDialogEventBus; + this.availabilityChecker = availabilityChecker; + } + + @Override + public View start(final ActionDefinition definition, ActionListener listener) { + View view = super.start(definition, listener); + final Component button = view.asVaadinComponent(); + chooseDialogEventBus.addHandler(SelectionChangedEvent.class, new SelectionChangedEvent.Handler() { + + @Override + public void onSelectionChanged(SelectionChangedEvent event) { + Set itemIds = event.getItemIds(); + if (itemIds == null || itemIds.isEmpty()) { + itemIds = Collections.emptySet(); + } + + AvailabilityDefinition availability = definition.getAvailability(); + button.setEnabled(availabilityChecker.isAvailable(availability, Lists.newLinkedList(itemIds))); + } + }); + return new ViewAdapter(button); + } + +} diff --git a/magnolia-ui-contentapp/src/test/java/info/magnolia/ui/contentapp/ContentAppTest.java b/magnolia-ui-contentapp/src/test/java/info/magnolia/ui/contentapp/ContentAppTest.java index 0623a67..a15798c 100644 --- a/magnolia-ui-contentapp/src/test/java/info/magnolia/ui/contentapp/ContentAppTest.java +++ b/magnolia-ui-contentapp/src/test/java/info/magnolia/ui/contentapp/ContentAppTest.java @@ -50,8 +50,11 @@ import info.magnolia.ui.api.context.UiContext; import info.magnolia.ui.api.event.ChooseDialogEventBus; import info.magnolia.ui.contentapp.browser.ConfiguredBrowserSubAppDescriptor; import info.magnolia.ui.contentapp.definition.ConfiguredContentSubAppDescriptor; +import info.magnolia.ui.contentapp.renderer.SelectionSensitiveActionRenderer; import info.magnolia.ui.dialog.DialogView; import info.magnolia.ui.dialog.actionarea.ActionAreaPresenter; +import info.magnolia.ui.dialog.actionarea.definition.ActionRendererDefinition; +import info.magnolia.ui.dialog.actionarea.definition.EditorActionAreaDefinition; import info.magnolia.ui.dialog.choosedialog.ChooseDialogPresenter; import info.magnolia.ui.dialog.choosedialog.ChooseDialogView; import info.magnolia.ui.dialog.definition.ChooseDialogDefinition; @@ -65,6 +68,10 @@ import info.magnolia.ui.vaadin.integration.contentconnector.DefaultContentConnec import info.magnolia.ui.vaadin.integration.contentconnector.JcrContentConnectorDefinition; import info.magnolia.ui.workbench.definition.ConfiguredWorkbenchDefinition; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + import javax.inject.Inject; import javax.inject.Named; @@ -125,6 +132,27 @@ public class ContentAppTest { } @Test + public void testAddAvailabilityActionRenderer() throws Exception { + // GIVEN + ConfiguredChooseDialogDefinition definition = mock(ConfiguredChooseDialogDefinition.class); + Map rendereres = new HashMap(); + + ContentApp app = new ContentApp(appContext, mock(AppView.class), componentProvider); + Method privateMethod = ContentApp.class.getDeclaredMethod("addAvailabilityActionRenderer", ChooseDialogDefinition.class); + privateMethod.setAccessible(true); + + // WHEN + when(definition.getActionArea()).thenReturn(mock(EditorActionAreaDefinition.class)); + when(definition.getActionArea().getActionRenderers()).thenReturn(rendereres); + definition = (ConfiguredChooseDialogDefinition) privateMethod.invoke(app, definition); + + // THEN + assertTrue(rendereres.size() > 0); + assertTrue(definition.getActionArea().getActionRenderers().containsKey("commit")); + assertEquals(SelectionSensitiveActionRenderer.class, definition.getActionArea().getActionRenderers().get("commit").getRendererClass()); + } + + @Test public void testCreateComponentProviderWithImageProviderBinding() throws Exception { // GIVEN // add imageProvider config diff --git a/magnolia-ui-contentapp/src/test/java/info/magnolia/ui/contentapp/renderer/SelectionSensitiveActionRendererTest.java b/magnolia-ui-contentapp/src/test/java/info/magnolia/ui/contentapp/renderer/SelectionSensitiveActionRendererTest.java new file mode 100644 index 0000000..235dcbf --- /dev/null +++ b/magnolia-ui-contentapp/src/test/java/info/magnolia/ui/contentapp/renderer/SelectionSensitiveActionRendererTest.java @@ -0,0 +1,117 @@ +/** + * This file Copyright (c) 2015 Magnolia International + * Ltd. (http://www.magnolia-cms.com). All rights reserved. + * + * + * This file is dual-licensed under both the Magnolia + * Network Agreement and the GNU General Public License. + * You may elect to use one or the other of these licenses. + * + * This file is distributed in the hope that it will be + * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT. + * Redistribution, except as permitted by whichever of the GPL + * or MNA you select, is prohibited. + * + * 1. For the GPL license (GPL), you can redistribute and/or + * modify this file under the terms of the GNU General + * Public License, Version 3, as published by the Free Software + * Foundation. You should have received a copy of the GNU + * General Public License, Version 3 along with this program; + * if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * 2. For the Magnolia Network Agreement (MNA), this file + * and the accompanying materials are made available under the + * terms of the MNA which accompanies this distribution, and + * is available at http://www.magnolia-cms.com/mna.html + * + * Any modifications to this file must keep this entire header + * intact. + * + */ +package info.magnolia.ui.contentapp.renderer; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.*; + +import info.magnolia.event.EventBus; +import info.magnolia.event.SimpleEventBus; +import info.magnolia.test.MgnlTestCase; +import info.magnolia.ui.api.action.ActionDefinition; +import info.magnolia.ui.api.availability.AvailabilityChecker; +import info.magnolia.ui.api.availability.ConfiguredAvailabilityDefinition; +import info.magnolia.ui.api.view.View; +import info.magnolia.ui.dialog.actionarea.ActionListener; +import info.magnolia.ui.workbench.event.SelectionChangedEvent; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for {@link SelectionSensitiveActionRenderer}. + */ +public class SelectionSensitiveActionRendererTest extends MgnlTestCase { + + private ActionListener actionListener; + private ActionDefinition actionDefinition; + private SelectionSensitiveActionRenderer renderer; + private EventBus chooseDialogEventBus; + private Set itemId; + private SelectionChangedEvent event; + private AvailabilityChecker availabilityChecker; + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + // Init + this.chooseDialogEventBus = new SimpleEventBus(); + + this.availabilityChecker = mock(AvailabilityChecker.class); + this.actionDefinition = mock(ActionDefinition.class); + this.actionListener = mock(ActionListener.class); + ConfiguredAvailabilityDefinition availability = mock(ConfiguredAvailabilityDefinition.class); + + this.renderer = new SelectionSensitiveActionRenderer(chooseDialogEventBus, availabilityChecker); + this.itemId = new HashSet(); + itemId.add("one"); + this.event = new SelectionChangedEvent(itemId); + + when(actionDefinition.getAvailability()).thenReturn(availability); + when(availabilityChecker.isAvailable(any(ConfiguredAvailabilityDefinition.class), anyList())).thenReturn(true); + } + + @Test + public void isEnabledForValidSelection() { + // GIVEN + when(availabilityChecker.isAvailable(any(ConfiguredAvailabilityDefinition.class), anyList())).thenReturn(true); + View view = renderer.start(actionDefinition, actionListener); + + // WHEN + // valid change event send, availability ok + chooseDialogEventBus.fireEvent(event); + + // THEN + assertTrue(view.asVaadinComponent().isEnabled()); + } + + @Test + public void isDisabledForInvalidSelection() { + // GIVEN + when(availabilityChecker.isAvailable(any(ConfiguredAvailabilityDefinition.class), anyList())).thenReturn(false); + View view = renderer.start(actionDefinition, actionListener); + + // WHEN + // valid change event send, availability ko + chooseDialogEventBus.fireEvent(event); + + // THEN + assertFalse(view.asVaadinComponent().isEnabled()); + } +}