    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.commons.scxml.model;
    18
    19  import java.net.URL;
    20  import java.util.ArrayList;
    21  import java.util.List;
    22
    23  import junit.framework.Test;
    24  import junit.framework.TestCase;
    25  import junit.framework.TestSuite;
    26
    27  import org.apache.commons.scxml.SCXMLExecutor;
    28  import org.apache.commons.scxml.SCXMLTestHelper;
    29  import org.apache.commons.scxml.env.jsp.ELEvaluator;
    30
    31  public class CustomActionTest extends TestCase {
    32
    33      public CustomActionTest(String testName) {
    34          super(testName);
    35      }
    36
    37      public static Test suite() {
    38          return new TestSuite(CustomActionTest.class);
    39      }
    40
    41      public static void main(String args[]) {
    42          String[] testCaseName = { CustomActionTest.class.getName()};
    43          junit.textui.TestRunner.main(testCaseName);
    44      }
    45
    46      private URL hello01, custom01, external01, override01, payload01, payload02;
    47      private SCXMLExecutor exec;
    48
    49      /***
    50       * Set up instance variables required by this test case.
    51       */
    52      public void setUp() {
    53          hello01 = this.getClass().getClassLoader().
    54              getResource("org/apache/commons/scxml/hello-world.xml");
    55          custom01 = this.getClass().getClassLoader().
    56              getResource("org/apache/commons/scxml/custom-hello-world-01.xml");
    57          external01 = this.getClass().getClassLoader().
    58              getResource("org/apache/commons/scxml/external-hello-world.xml");
    59          override01 = this.getClass().getClassLoader().
    60              getResource("org/apache/commons/scxml/custom-hello-world-03.xml");
    61          payload01 = this.getClass().getClassLoader().
    62              getResource("org/apache/commons/scxml/custom-hello-world-04-jexl.xml");
    63          payload02 = this.getClass().getClassLoader().
    64              getResource("org/apache/commons/scxml/custom-hello-world-04-el.xml");
    65      }
    66
    67      /***
    68       * Tear down instance variables required by this test case.
    69       */
    70      public void tearDown() {
    71          hello01 = custom01 = external01 = payload01 = payload02 = null;
    72          exec = null;
    73      }
    74
    75      public void testAddGoodCustomAction01() {
    76          try {
    77              new CustomAction("http://my.actions.domain/CUSTOM", "hello",
    78                  Hello.class);
    79          } catch (IllegalArgumentException iae) {
    80              fail("Failed to add custom action &quot;Hello&quot;");
    81          }
    82      }
    83
    84      public void testAddBadCustomAction01() {
    85          try {
    86              new CustomAction(null, "hello", Hello.class);
    87              fail("Added custom action with illegal namespace");
    88          } catch (IllegalArgumentException iae) {
    89              // Expected
    90          }
    91      }
    92
    93      public void testAddBadCustomAction02() {
    94          try {
    95              new CustomAction("  ", "hello", Hello.class);
    96              fail("Added custom action with illegal namespace");
    97          } catch (IllegalArgumentException iae) {
    98              // Expected
    99          }
    100     }
    101
    102     public void testAddBadCustomAction03() {
    103         try {
    104             new CustomAction("http://my.actions.domain/CUSTOM", "",
    105                 Hello.class);
    106             fail("Added custom action with illegal local name");
    107         } catch (IllegalArgumentException iae) {
    108             // Expected
    109         }
    110     }
    111
    112     public void testAddBadCustomAction04() {
    113         try {
    114             new CustomAction("http://my.actions.domain/CUSTOM", "  ",
    115                 Hello.class);
    116             fail("Added custom action with illegal local name");
    117         } catch (IllegalArgumentException iae) {
    118             // Expected
    119         }
    120     }
    121
    122     public void testAddBadCustomAction05() {
    123         try {
    124             new CustomAction("http://my.actions.domain/CUSTOM", "foo",
    125                 this.getClass());
    126             fail("Added custom action which is not an Action class subtype");
    127         } catch (IllegalArgumentException iae) {
    128             // Expected
    129         }
    130     }
    131
    132     public void testAddBadCustomAction06() {
    133         try {
    134             new CustomAction("http://www.w3.org/2005/07/scxml", "foo",
    135                 this.getClass());
    136             fail("Added custom action in the SCXML namespace");
    137         } catch (IllegalArgumentException iae) {
    138             // Expected
    139         }
    140     }
    141
    142     // Hello World example using the SCXML <log> action
    143     public void testHelloWorld() {
    144         // (1) Get a SCXMLExecutor
    145         exec = SCXMLTestHelper.getExecutor(hello01);
    146         // (2) Single, final state
    147         assertEquals("hello", ((State) exec.getCurrentStatus().getStates().
    148                 iterator().next()).getId());
    149         assertTrue(exec.getCurrentStatus().isFinal());
    150     }
    151
    152     // Hello World example using a custom <hello> action
    153     public void testCustomActionHelloWorld() {
    154         // (1) Form a list of custom actions defined in the SCXML
    155         //     document (and any included documents via "src" attributes)
    156         CustomAction ca1 =
    157             new CustomAction("http://my.custom-actions.domain/CUSTOM1",
    158                              "hello", Hello.class);
    159         // Register the same action under a different name, just to test
    160         // multiple custom actions
    161         CustomAction ca2 =
    162             new CustomAction("http://my.custom-actions.domain/CUSTOM2",
    163                              "bar", Hello.class);
    164         List customActions = new ArrayList();
    165         customActions.add(ca1);
    166         customActions.add(ca2);
    167         // (2) Parse the document with a custom digester.
    168         SCXML scxml = SCXMLTestHelper.digest(custom01, customActions);
    169         // (3) Get a SCXMLExecutor
    170         exec = SCXMLTestHelper.getExecutor(scxml);
    171         // (4) Single, final state
    172         assertEquals("custom", ((State) exec.getCurrentStatus().getStates().
    173                 iterator().next()).getId());
    174         assertTrue(exec.getCurrentStatus().isFinal());
    175     }
    176
    177     // Hello World example using custom <my:hello> action
    178     // as part of an external state source (src attribute)
    179     public void testCustomActionExternalSrcHelloWorld() {
    180         // (1) Form a list of custom actions defined in the SCXML
    181         //     document (and any included documents via "src" attributes)
    182         CustomAction ca =
    183             new CustomAction("http://my.custom-actions.domain/CUSTOM",
    184                              "hello", Hello.class);
    185         List customActions = new ArrayList();
    186         customActions.add(ca);
    187         // (2) Parse the document with a custom digester.
    188         SCXML scxml = SCXMLTestHelper.digest(external01, customActions);
    189         // (3) Get a SCXMLExecutor
    190         exec = SCXMLTestHelper.getExecutor(scxml);
    191         // (4) Single, final state
    192         assertEquals("custom", ((State) exec.getCurrentStatus().getStates().
    193             iterator().next()).getId());
    194     }
    195
    196     // Hello World example using custom <my:send> action
    197     // (overriding SCXML local name "send")
    198     public void testCustomActionOverrideLocalName() {
    199         // (1) List of custom actions, use same local name as SCXML action
    200         CustomAction ca =
    201             new CustomAction("http://my.custom-actions.domain/CUSTOM",
    202                              "send", Hello.class);
    203         List customActions = new ArrayList();
    204         customActions.add(ca);
    205         // (2) Parse the document with a custom digester.
    206         SCXML scxml = SCXMLTestHelper.digest(override01, customActions);
    207         // (3) Get a SCXMLExecutor
    208         exec = SCXMLTestHelper.getExecutor(scxml);
    209         // (4) Single, final state
    210         assertEquals("custom", ((State) exec.getCurrentStatus().getStates().
    211             iterator().next()).getId());
    212     }
    213
    214     // The custom action defined by Hello.class should be called
    215     // to execute() exactly 5 times upto this point
    216     public void testCustomActionCallbacks() {
    217         assertEquals(5, Hello.callbacks);
    218     }
    219
    220     // Hello World example using custom <my:hello> action that generates an
    221     // event which has the payload examined with JEXL expressions
    222     public void testCustomActionEventPayloadHelloWorldJexl() {
    223         // (1) Form a list of custom actions defined in the SCXML
    224         //     document (and any included documents via "src" attributes)
    225         CustomAction ca =
    226             new CustomAction("http://my.custom-actions.domain/CUSTOM",
    227                              "hello", Hello.class);
    228         List customActions = new ArrayList();
    229         customActions.add(ca);
    230         // (2) Parse the document with a custom digester.
    231         SCXML scxml = SCXMLTestHelper.digest(payload01, customActions);
    232         // (3) Get a SCXMLExecutor
    233         exec = SCXMLTestHelper.getExecutor(scxml);
    234         // (4) Single, final state
    235         assertEquals("Invalid intermediate state",
    236                      "custom1", ((State) exec.getCurrentStatus().getStates().
    237                                 iterator().next()).getId());
    238         // (5) Verify datamodel variable is correct
    239         assertEquals("Missing helloName1 in root context", "custom04a",
    240                      (String) exec.getRootContext().get("helloName1"));
    241         // (6) Check use of payload in non-initial state
    242         SCXMLTestHelper.fireEvent(exec, "custom.next");
    243         // (7) Verify correct end state
    244         assertEquals("Missing helloName1 in root context", "custom04b",
    245                 (String) exec.getRootContext().get("helloName1"));
    246         assertEquals("Invalid final state",
    247                 "end", ((State) exec.getCurrentStatus().getStates().
    248                 iterator().next()).getId());
    249         assertTrue(exec.getCurrentStatus().isFinal());
    250     }
    251
    252     // Hello World example using custom <my:hello> action that generates an
    253     // event which has the payload examined with EL expressions
    254     public void testCustomActionEventPayloadHelloWorldEL() {
    255         // (1) Form a list of custom actions defined in the SCXML
    256         //     document (and any included documents via "src" attributes)
    257         CustomAction ca =
    258             new CustomAction("http://my.custom-actions.domain/CUSTOM",
    259                              "hello", Hello.class);
    260         List customActions = new ArrayList();
    261         customActions.add(ca);
    262         // (2) Parse the document with a custom digester.
    263         SCXML scxml = SCXMLTestHelper.digest(payload02, customActions);
    264         // (3) Get a SCXMLExecutor
    265         exec = SCXMLTestHelper.getExecutor(new ELEvaluator(), scxml);
    266         // (4) Single, final state
    267         assertEquals("Invalid final state",
    268                      "custom", ((State) exec.getCurrentStatus().getStates().
    269                                 iterator().next()).getId());
    270         // (5) Verify datamodel variable is correct
    271         assertEquals("Missing helloName1 in root context", "custom04",
    272                      (String) exec.getRootContext().get("helloName1"));
    273     }
    274
    275 }
    276