blob: 7b9850d152a3f0277553229c8912e4fb41d89f4a [file] [log] [blame]
/*
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.wiki.workflow;
import org.apache.wiki.api.exceptions.WikiException;
import org.apache.wiki.auth.GroupPrincipal;
import org.apache.wiki.auth.WikiPrincipal;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.security.Principal;
import java.util.Date;
public class WorkflowTest
{
Workflow w;
Task initTask;
Decision decision;
Task finishTask;
String ATTR = "TestAttribute";
@BeforeEach
public void setUp() throws Exception
{
// Create workflow; owner is test user
w = new Workflow("workflow.myworkflow", new WikiPrincipal("Owner1"));
// Create custom initialization task
initTask = new TaskTest.NormalTask(w);
// Create finish task
finishTask = new TaskTest.NormalTask(w);
// Create an intermetidate decision step
Principal actor = new GroupPrincipal("Admin");
decision = new SimpleDecision(w, "decision.AdminDecision", actor);
// Hook the steps together
initTask.addSuccessor(Outcome.STEP_COMPLETE, decision);
decision.addSuccessor(Outcome.DECISION_APPROVE, finishTask);
// Stash page name as message attribute
w.addMessageArgument("MyPage");
// Set workflow's first step
w.setFirstStep(initTask);
}
@Test
public void testWorkflow()
{
// Make sure everything is set to their proper default values
Assertions.assertNull(w.getCurrentStep());
Assertions.assertNull(w.getCurrentActor());
Assertions.assertEquals(0, w.getHistory().size());
Assertions.assertEquals(Workflow.ID_NOT_SET, w.getId());
Assertions.assertNull(w.getWorkflowManager());
Assertions.assertEquals(new WikiPrincipal("Owner1"), w.getOwner());
Assertions.assertEquals(Workflow.CREATED, w.getCurrentState());
Assertions.assertEquals(Workflow.TIME_NOT_SET, w.getStartTime());
Assertions.assertEquals(Workflow.TIME_NOT_SET, w.getEndTime());
}
@Test
public void testSetWorkflowManager()
{
Assertions.assertNull(w.getWorkflowManager());
WorkflowManager m = new DefaultWorkflowManager();
w.setWorkflowManager(m);
Assertions.assertEquals(m, w.getWorkflowManager());
}
@Test
public void testGetSetAttribute()
{
Assertions.assertNull(w.getAttribute(ATTR));
w.setAttribute(ATTR, "Test String");
Assertions.assertNotNull(w.getAttribute(ATTR));
Assertions.assertEquals("Test String", w.getAttribute(ATTR));
}
@Test
public void testGetMessageArgs() throws WikiException
{
Object[] args;
// Before start, arg1=Owner1, arg2=- (no current actor), arg3=MyPage
args = w.getMessageArguments();
Assertions.assertEquals("Owner1", args[0]);
Assertions.assertEquals("-", args[1]);
Assertions.assertEquals("MyPage", args[2]);
// After start (at Decision), arg1=Owner1, arg2=Admin, arg3=MyPage
w.start();
args = w.getMessageArguments();
Assertions.assertEquals("Owner1", args[0]);
Assertions.assertEquals("Admin", args[1]);
Assertions.assertEquals("MyPage", args[2]);
// After end, arg1=Owner1, arg2=-, arg3=MyPage
decision.decide(Outcome.DECISION_APPROVE);
args = w.getMessageArguments();
Assertions.assertEquals("Owner1", args[0]);
Assertions.assertEquals("-", args[1]);
Assertions.assertEquals("MyPage", args[2]);
}
@Test
public void testGetMessageArgObjects()
{
// Try passing some valid object types: Date, Number
w.addMessageArgument(new Date());
w.addMessageArgument(new Integer(1));
w.addMessageArgument(new Double(2));
w.addMessageArgument(new BigDecimal(3.14));
// Try passing an invalid one: e.g., a Workflow (it should Assertions.fail)
try
{
w.addMessageArgument(w);
}
catch (IllegalArgumentException e)
{
// Swallow
return;
}
// We should never get here
Assertions.fail("Illegal argument passed...");
}
@Test
public void testGetMessageKey()
{
Assertions.assertEquals("workflow.myworkflow", w.getMessageKey());
}
@Test
public void testGetOwner()
{
Assertions.assertEquals(new WikiPrincipal("Owner1"), w.getOwner());
}
@Test
public void testStart() throws WikiException
{
Assertions.assertFalse(w.isStarted());
w.start();
Assertions.assertTrue(w.isStarted());
}
@Test
public void testWaitstate() throws WikiException
{
w.start();
// Default workflow should have hit the Decision step and put itself
// into WAITING
Assertions.assertEquals(Workflow.WAITING, w.getCurrentState());
}
@Test
public void testRestart() throws WikiException
{
w.start();
// Default workflow should have hit the Decision step and put itself
// into WAITING
Assertions.assertEquals(Workflow.WAITING, w.getCurrentState());
w.restart();
Assertions.assertEquals(Workflow.WAITING, w.getCurrentState());
}
@Test
public void testAbortBeforeStart() throws WikiException
{
// Workflow hasn't been started yet
Assertions.assertFalse(w.isAborted());
w.abort();
Assertions.assertTrue(w.isAborted());
// Try to start anyway
try
{
w.start();
}
catch (IllegalStateException e)
{
// Swallow
return;
}
// We should never get here
Assertions.fail("Workflow allowed itself to be started even though it was aborted!");
}
@Test
public void testAbortDuringWait() throws WikiException
{
// Start workflow, then abort while in WAITING state
Assertions.assertFalse(w.isAborted());
w.start();
w.abort();
Assertions.assertTrue(w.isAborted());
// Try to restart anyway
try
{
w.restart();
}
catch (IllegalStateException e)
{
// Swallow
return;
}
// We should never get here
Assertions.fail("Workflow allowed itself to be re-started even though it was aborted!");
}
@Test
public void testAbortAfterCompletion() throws WikiException
{
// Start workflow, then abort after completion
Assertions.assertFalse(w.isAborted());
w.start();
Decision d = (Decision) w.getCurrentStep();
d.decide(Outcome.DECISION_APPROVE);
// Try to abort anyway
try
{
w.abort();
Assertions.assertTrue(w.isAborted());
}
catch (IllegalStateException e)
{
// Swallow
return;
}
// We should never get here
Assertions.fail("Workflow allowed itself to be aborted even though it was completed!");
}
@Test
public void testCurrentState() throws WikiException
{
Assertions.assertEquals(Workflow.CREATED, w.getCurrentState());
w.start();
Assertions.assertEquals(Workflow.WAITING, w.getCurrentState());
Decision d = (Decision) w.getCurrentStep();
d.decide(Outcome.DECISION_APPROVE);
Assertions.assertEquals(Workflow.COMPLETED, w.getCurrentState());
}
@Test
public void testCurrentStep() throws WikiException
{
Assertions.assertNull(w.getCurrentStep());
w.start();
// Workflow stops at the decision step
Assertions.assertEquals(decision, w.getCurrentStep());
Decision d = (Decision) w.getCurrentStep();
d.decide(Outcome.DECISION_APPROVE);
// After we decide, it blows through step 3 and leaves us with a null
// step (done)
Assertions.assertNull(w.getCurrentStep());
}
@Test
public void testPreviousStep() throws WikiException
{
// If not started, no previous steps available for anything
Assertions.assertNull(w.getPreviousStep());
Assertions.assertEquals(null, w.previousStep(initTask));
Assertions.assertEquals(null, w.previousStep(decision));
Assertions.assertEquals(null, w.previousStep(finishTask));
// Once we start, initTask and decisions' predecessors are known, but
// finish task is indeterminate
w.start();
Assertions.assertEquals(null, w.previousStep(initTask));
Assertions.assertEquals(initTask, w.previousStep(decision));
Assertions.assertEquals(null, w.previousStep(finishTask));
// Once we decide, the finish task returns the correct predecessor
Decision d = (Decision) w.getCurrentStep();
d.decide(Outcome.DECISION_APPROVE);
Assertions.assertEquals(null, w.previousStep(initTask));
Assertions.assertEquals(initTask, w.previousStep(decision));
Assertions.assertEquals(decision, w.previousStep(finishTask));
}
@Test
public void testCurrentActor() throws WikiException
{
// Before starting, actor should be null
Assertions.assertNull(w.getCurrentActor());
// After starting, actor should be GroupPrincipal Admin
w.start();
Assertions.assertEquals(new GroupPrincipal("Admin"), w.getCurrentActor());
// After decision, actor should be null again
Decision d = (Decision) w.getCurrentStep();
d.decide(Outcome.DECISION_APPROVE);
Assertions.assertNull(w.getCurrentActor());
}
@Test
public void testHistory() throws WikiException
{
Assertions.assertEquals(0, w.getHistory().size());
w.start();
Assertions.assertEquals(2, w.getHistory().size());
Decision d = (Decision) w.getCurrentStep();
d.decide(Outcome.DECISION_APPROVE);
Assertions.assertEquals(3, w.getHistory().size());
}
@Test
public void testGetStartTime() throws WikiException
{
// Start time should be not be set until we start the workflow
Assertions.assertEquals(Workflow.TIME_NOT_SET, w.getStartTime());
w.start();
Assertions.assertFalse(Workflow.TIME_NOT_SET == w.getStartTime());
Decision d = (Decision) w.getCurrentStep();
d.decide(Outcome.DECISION_APPROVE);
Assertions.assertFalse(Workflow.TIME_NOT_SET == w.getStartTime());
}
@Test
public void testGetEndTime() throws WikiException
{
// End time should be not set until we finish all 3 steps
Assertions.assertEquals(Workflow.TIME_NOT_SET, w.getEndTime());
w.start();
Assertions.assertEquals(Workflow.TIME_NOT_SET, w.getEndTime());
Decision d = (Decision) w.getCurrentStep();
d.decide(Outcome.DECISION_APPROVE);
Assertions.assertFalse(Workflow.TIME_NOT_SET == w.getEndTime());
}
@Test
public void testIsCompleted() throws WikiException
{
// Workflow isn't completed until we finish all 3 steps
Assertions.assertFalse(w.isCompleted());
w.start();
Assertions.assertFalse(w.isCompleted());
Decision d = (Decision) w.getCurrentStep();
d.decide(Outcome.DECISION_APPROVE);
Assertions.assertTrue(w.isCompleted());
}
@Test
public void testIsStarted() throws WikiException
{
Assertions.assertFalse(w.isStarted());
w.start();
Assertions.assertTrue(w.isStarted());
}
@Test
public void testStartTwice() throws WikiException
{
w.start();
try
{
w.start();
}
catch (IllegalStateException e)
{
// Swallow
return;
}
// We should never get here
Assertions.fail("Workflow allowed itself to be started twice!");
}
@Test
public void testSetId()
{
Assertions.assertEquals(Workflow.ID_NOT_SET, w.getId());
w.setId(1001);
Assertions.assertEquals(1001, w.getId());
}
}