From 0646ed443239ec4213af0fa7141d68a1ce97542c Mon Sep 17 00:00:00 2001
From: Robert Scott <code@humanleg.org.uk>
Date: Sun, 28 Oct 2018 13:35:42 +0000
Subject: [PATCH v1 2/2] RelationEditorActionsTest: fix for non-headless mode

Splitting DeleteCurrentRelationAction and SetRoleAction out into their own tests
---
 .../josm/gui/ConditionalOptionPaneUtil.java        | 16 +---
 .../actions/RelationEditorActionsTest.java         | 97 +++++++++++++++++++++-
 2 files changed, 96 insertions(+), 17 deletions(-)

diff --git a/src/org/openstreetmap/josm/gui/ConditionalOptionPaneUtil.java b/src/org/openstreetmap/josm/gui/ConditionalOptionPaneUtil.java
index 0f4d3ac0a..3a304e341 100644
--- a/src/org/openstreetmap/josm/gui/ConditionalOptionPaneUtil.java
+++ b/src/org/openstreetmap/josm/gui/ConditionalOptionPaneUtil.java
@@ -115,7 +115,6 @@ public final class ConditionalOptionPaneUtil {
      *
      * @return the option selected by user.
      *         {@link JOptionPane#CLOSED_OPTION} if the dialog was closed.
-     *         {@link JOptionPane#YES_OPTION} if <code>GraphicsEnvironment.isHeadless</code> returns <code>true</code>
      */
     public static int showOptionDialog(String preferenceKey, Component parent, Object message, String title, int optionType,
             int messageType, Object[] options, Object defaultOption) {
@@ -123,12 +122,7 @@ public final class ConditionalOptionPaneUtil {
         if (isYesOrNo(ret))
             return ret;
         MessagePanel pnl = new MessagePanel(message, isInBulkOperation(preferenceKey));
-        if (GraphicsEnvironment.isHeadless()) {
-            // for unit tests
-            ret = JOptionPane.YES_OPTION;
-        } else {
-            ret = JOptionPane.showOptionDialog(parent, pnl, title, optionType, messageType, null, options, defaultOption);
-        }
+        ret = JOptionPane.showOptionDialog(parent, pnl, title, optionType, messageType, null, options, defaultOption);
         if (isYesOrNo(ret)) {
             pnl.getNotShowAgain().store(preferenceKey, ret);
         }
@@ -161,7 +155,6 @@ public final class ConditionalOptionPaneUtil {
      *
      *
      * @return true, if the selected option is equal to <code>trueOption</code>, otherwise false.
-     *         {@code trueOption} if <code>GraphicsEnvironment.isHeadless</code> returns <code>true</code>
      *
      * @see JOptionPane#INFORMATION_MESSAGE
      * @see JOptionPane#WARNING_MESSAGE
@@ -173,12 +166,7 @@ public final class ConditionalOptionPaneUtil {
         if (isYesOrNo(ret))
             return ret == trueOption;
         MessagePanel pnl = new MessagePanel(message, isInBulkOperation(preferenceKey));
-        if (GraphicsEnvironment.isHeadless()) {
-            // for unit tests
-            ret = trueOption;
-        } else {
-            ret = JOptionPane.showConfirmDialog(parent, pnl, title, optionType, messageType);
-        }
+        ret = JOptionPane.showConfirmDialog(parent, pnl, title, optionType, messageType);
         if (isYesOrNo(ret)) {
             pnl.getNotShowAgain().store(preferenceKey, ret);
         }
diff --git a/test/unit/org/openstreetmap/josm/gui/dialogs/relation/actions/RelationEditorActionsTest.java b/test/unit/org/openstreetmap/josm/gui/dialogs/relation/actions/RelationEditorActionsTest.java
index 87c18675e..a5e06b227 100644
--- a/test/unit/org/openstreetmap/josm/gui/dialogs/relation/actions/RelationEditorActionsTest.java
+++ b/test/unit/org/openstreetmap/josm/gui/dialogs/relation/actions/RelationEditorActionsTest.java
@@ -1,6 +1,23 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.gui.dialogs.relation.actions;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.awt.Component;
+import java.awt.Container;
+import javax.swing.Icon;
+import javax.swing.JOptionPane;
+import javax.swing.text.JTextComponent;
+
+import org.openstreetmap.josm.testutils.mockers.JOptionPaneSimpleMocker;
+import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
+
+import com.google.common.collect.ImmutableMap;
+
+import mockit.Mock;
+import mockit.MockUp;
+
 import org.junit.Test;
 
 /**
@@ -9,10 +26,10 @@ import org.junit.Test;
 public class RelationEditorActionsTest extends AbstractRelationEditorActionTest {
 
     /**
-     * Check that all actions do not crash.
+     * Check that all dialog-less actions do not crash.
      */
     @Test
-    public void testAllActions() {
+    public void testNoDialogActions() {
         new AddSelectedAfterSelection(relationEditorAccess).actionPerformed(null);
         new AddSelectedBeforeSelection(relationEditorAccess).actionPerformed(null);
         new AddSelectedAtStartAction(relationEditorAccess).actionPerformed(null);
@@ -27,7 +44,6 @@ public class RelationEditorActionsTest extends AbstractRelationEditorActionTest
         new PasteMembersAction(relationEditorAccess).actionPerformed(null);
 
         new SelectAction(relationEditorAccess).actionPerformed(null);
-        new DeleteCurrentRelationAction(relationEditorAccess).actionPerformed(null);
 
         new DownloadIncompleteMembersAction(relationEditorAccess, "downloadincomplete").actionPerformed(null);
         new DownloadSelectedIncompleteMembersAction(relationEditorAccess).actionPerformed(null);
@@ -47,7 +63,82 @@ public class RelationEditorActionsTest extends AbstractRelationEditorActionTest
         new SortAction(relationEditorAccess).actionPerformed(null);
         new SortBelowAction(relationEditorAccess).actionPerformed(null);
         new ReverseAction(relationEditorAccess).actionPerformed(null);
+    }
+
+    /**
+     * Test DeleteCurrentRelationAction
+     */
+    @Test
+    public void testDeleteCurrentRelationAction() {
+        final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(
+            ImmutableMap.<String, Object>of(
+                "<html>\n  <head>\n    \n  </head>\n  <body>\n    You are about to delete 1 "
+                + "relation:\n\n    "
+                + "<ul>\n      <li>\n        incomplete\n      </li>\n    </ul>\n    <br>\n    "
+                + "This step is rarely necessary and cannot be undone easily after being \n    "
+                + "uploaded to the server.<br>Do you really want to delete?\n  </body>\n</html>\n", JOptionPane.YES_OPTION,
+                "<html>\n  <head>\n    \n  </head>\n  <body>\n    You are about to delete incomplete "
+                + "objects.<br>This will cause problems \n    because you don\'t see the real object.<br>"
+                + "Do you really want to delete?\n  </body>\n</html>\n",
+                JOptionPane.YES_OPTION
+            )
+        ) {
+            public String getStringFromOriginalMessage(Object originalMessage) {
+                return ((JTextComponent) ((Container) originalMessage).getComponent(0)).getText();
+            }
+        };
+
+        new DeleteCurrentRelationAction(relationEditorAccess).actionPerformed(null);
+
+        assertEquals(2, jopsMocker.getInvocationLog().size());
+
+        Object[] invocationLogEntry = jopsMocker.getInvocationLog().get(0);
+        assertEquals(JOptionPane.YES_OPTION, (int) invocationLogEntry[0]);
+        assertEquals("Delete relation?", invocationLogEntry[2]);
+
+        invocationLogEntry = jopsMocker.getInvocationLog().get(1);
+        assertEquals(JOptionPane.YES_OPTION, (int) invocationLogEntry[0]);
+        assertEquals("Delete confirmation", invocationLogEntry[2]);
+    }
+
+    /**
+     * Test SetRoleAction
+     */
+    @Test
+    public void testSetRoleAction() {
+        final JOptionPaneSimpleMocker.MessagePanelMocker mpMocker = new JOptionPaneSimpleMocker.MessagePanelMocker();
+        // JOptionPaneSimpleMocker doesn't handle showOptionDialog calls because of their potential
+        // complexity, but this is quite a simple use of showOptionDialog which we can mock
+        // from scratch.
+        final boolean[] jopMockerCalled = new boolean[] { false };
+        final MockUp<JOptionPane> jopMocker = new MockUp<JOptionPane> () {
+            @Mock
+            public int showOptionDialog(
+                Component parentComponent,
+                Object message,
+                String title,
+                int optionType,
+                int messageType,
+                Icon icon,
+                Object[] options,
+                Object initialValue
+            ) {
+                assertEquals(
+                    "<html>You are setting an empty role on 0 objects.<br>This is equal to deleting the "
+                    + "roles of these objects.<br>Do you really want to apply the new role?</html>",
+                    mpMocker.getOriginalMessage((ConditionalOptionPaneUtil.MessagePanel) message).toString()
+                );
+                assertEquals(
+                    "Confirm empty role",
+                    title
+                );
+                jopMockerCalled[0] = true;
+                return JOptionPane.YES_OPTION;
+            }
+        };
 
         new SetRoleAction(relationEditorAccess).actionPerformed(null);
+
+        assertTrue(jopMockerCalled[0]);
     }
 }
-- 
2.11.0

