Package org.camunda.bpm.engine.test.history

Source Code of org.camunda.bpm.engine.test.history.HistoricCaseActivityInstanceTest

/* Licensed 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.camunda.bpm.engine.test.history;

import static org.camunda.bpm.engine.impl.cmmn.execution.CaseExecutionState.ACTIVE;
import static org.camunda.bpm.engine.impl.cmmn.execution.CaseExecutionState.AVAILABLE;
import static org.camunda.bpm.engine.impl.cmmn.execution.CaseExecutionState.COMPLETED;
import static org.camunda.bpm.engine.impl.cmmn.execution.CaseExecutionState.DISABLED;
import static org.camunda.bpm.engine.impl.cmmn.execution.CaseExecutionState.ENABLED;
import static org.camunda.bpm.engine.impl.cmmn.execution.CaseExecutionState.SUSPENDED;
import static org.camunda.bpm.engine.impl.cmmn.execution.CaseExecutionState.TERMINATED;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
import static org.junit.Assert.assertThat;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.camunda.bpm.engine.ProcessEngineException;
import org.camunda.bpm.engine.history.HistoricCaseActivityInstance;
import org.camunda.bpm.engine.history.HistoricCaseActivityInstanceQuery;
import org.camunda.bpm.engine.impl.AbstractQuery;
import org.camunda.bpm.engine.impl.cmmn.execution.CaseExecutionState;
import org.camunda.bpm.engine.impl.history.event.HistoricCaseActivityInstanceEventEntity;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricCaseActivityInstanceEntity;
import org.camunda.bpm.engine.impl.test.CmmnProcessEngineTestCase;
import org.camunda.bpm.engine.impl.util.ClockUtil;
import org.camunda.bpm.engine.query.Query;
import org.camunda.bpm.engine.query.QueryProperty;
import org.camunda.bpm.engine.runtime.CaseExecution;
import org.camunda.bpm.engine.runtime.CaseInstance;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.task.Task;
import org.camunda.bpm.engine.test.Deployment;
import org.hamcrest.Matcher;

/**
* @author Sebastian Menski
*/
public class HistoricCaseActivityInstanceTest extends CmmnProcessEngineTestCase {

  @Deployment(resources={"org/camunda/bpm/engine/test/api/cmmn/emptyStageCase.cmmn"})
  public void testHistoricCaseActivityInstanceProperties() {
    String activityId = "PI_Stage_1";

    createCaseInstance();
    CaseExecution stage = queryCaseExecutionByActivityId(activityId);
    HistoricCaseActivityInstance historicStage = queryHistoricActivityCaseInstance(activityId);

    assertEquals(stage.getId(), historicStage.getId());
    assertEquals(stage.getParentId(), historicStage.getParentCaseActivityInstanceId());
    assertEquals(stage.getCaseDefinitionId(), historicStage.getCaseDefinitionId());
    assertEquals(stage.getCaseInstanceId(), historicStage.getCaseInstanceId());
    assertEquals(stage.getActivityId(), historicStage.getCaseActivityId());
    assertEquals(stage.getActivityName(), historicStage.getCaseActivityName());

    manualStart(stage.getId());

    historicStage = queryHistoricActivityCaseInstance(activityId);
    assertNotNull(historicStage.getEndTime());
  }

  @Deployment
  public void testHistoricCaseActivityTaskStates() {
    String humanTaskId1 = "PI_HumanTask_1";
    String humanTaskId2 = "PI_HumanTask_2";
    String humanTaskId3 = "PI_HumanTask_3";

    // given
    String caseInstanceId = createCaseInstance().getId();
    String taskInstanceId1 = queryCaseExecutionByActivityId(humanTaskId1).getId();
    String taskInstanceId2 = queryCaseExecutionByActivityId(humanTaskId2).getId();
    String taskInstanceId3 = queryCaseExecutionByActivityId(humanTaskId3).getId();

    // human task 1 should enabled and human task 2 and 3 will be available cause the sentry is not fulfilled
    assertHistoricState(humanTaskId1, ENABLED);
    assertHistoricState(humanTaskId2, AVAILABLE);
    assertHistoricState(humanTaskId3, AVAILABLE);
    assertStateQuery(ENABLED, AVAILABLE, AVAILABLE);

    // when human task 1 is started
    manualStart(taskInstanceId1);

    // then human task 1 is active and human task 2 and 3 are still available
    assertHistoricState(humanTaskId1, ACTIVE);
    assertHistoricState(humanTaskId2, AVAILABLE);
    assertHistoricState(humanTaskId3, AVAILABLE);
    assertStateQuery(ACTIVE, AVAILABLE, AVAILABLE);

    // when human task 1 is completed
    complete(taskInstanceId1);

    // then human task 1 is completed and human task 2 is enabled and human task 3 is active
    assertHistoricState(humanTaskId1, COMPLETED);
    assertHistoricState(humanTaskId2, ENABLED);
    assertHistoricState(humanTaskId3, ACTIVE);
    assertStateQuery(COMPLETED, ENABLED, ACTIVE);

    // disable human task 2
    disable(taskInstanceId2);
    assertHistoricState(humanTaskId1, COMPLETED);
    assertHistoricState(humanTaskId2, DISABLED);
    assertHistoricState(humanTaskId3, ACTIVE);
    assertStateQuery(COMPLETED, DISABLED, ACTIVE);

    // re-enable human task 2
    reenable(taskInstanceId2);
    assertHistoricState(humanTaskId1, COMPLETED);
    assertHistoricState(humanTaskId2, ENABLED);
    assertHistoricState(humanTaskId3, ACTIVE);
    assertStateQuery(COMPLETED, ENABLED, ACTIVE);

    // suspend human task 3
    suspend(taskInstanceId3);
    assertHistoricState(humanTaskId1, COMPLETED);
    assertHistoricState(humanTaskId2, ENABLED);
    assertHistoricState(humanTaskId3, SUSPENDED);
    assertStateQuery(COMPLETED, ENABLED, SUSPENDED);

    // resume human task 3
    resume(taskInstanceId3);
    assertHistoricState(humanTaskId1, COMPLETED);
    assertHistoricState(humanTaskId2, ENABLED);
    assertHistoricState(humanTaskId3, ACTIVE);
    assertStateQuery(COMPLETED, ENABLED, ACTIVE);

    // when the case instance is suspended
    suspend(caseInstanceId);

    // then human task 2 and 3 are suspended
    assertHistoricState(humanTaskId1, COMPLETED);
    assertHistoricState(humanTaskId2, SUSPENDED);
    assertHistoricState(humanTaskId3, SUSPENDED);
    assertStateQuery(COMPLETED, SUSPENDED, SUSPENDED);

    // when case instance is re-activated
    reactivate(caseInstanceId);

    // then human task 2 is enabled and human task is active
    assertHistoricState(humanTaskId1, COMPLETED);
    assertHistoricState(humanTaskId2, ENABLED);
    assertHistoricState(humanTaskId3, ACTIVE);
    assertStateQuery(COMPLETED, ENABLED, ACTIVE);

    // when human task 3 is terminated
    terminate(taskInstanceId3);

    // then human task 2 and 3 are terminated caused by the exitCriteria of human task 2
    assertHistoricState(humanTaskId1, COMPLETED);
    assertHistoricState(humanTaskId2, TERMINATED);
    assertHistoricState(humanTaskId3, TERMINATED);
    assertStateQuery(COMPLETED, TERMINATED, TERMINATED);
  }

  @Deployment
  public void testHistoricCaseActivityEventListenerAndMilestoneStates() {
    String milestoneId = "PI_Milestone";
    String userEventId1 = "PI_UserEvent_1";
    String userEventId2 = "PI_UserEvent_2";

    // given
    String caseInstanceId = createCaseInstance().getId();
    String eventInstance1 = queryCaseExecutionByActivityId(userEventId1).getId();
    String eventInstance2 = queryCaseExecutionByActivityId(userEventId2).getId();

    // then milestone and user event 1 and 2 are available
    assertHistoricState(milestoneId, AVAILABLE);
    assertHistoricState(userEventId1, AVAILABLE);
    assertHistoricState(userEventId2, AVAILABLE);
    assertStateQuery(AVAILABLE, AVAILABLE, AVAILABLE);

    // suspend event user event 1 and 2
    suspend(eventInstance1);
    suspend(eventInstance2);
    assertHistoricState(milestoneId, AVAILABLE);
    assertHistoricState(userEventId1, SUSPENDED);
    assertHistoricState(userEventId2, SUSPENDED);
    assertStateQuery(AVAILABLE, SUSPENDED, SUSPENDED);

    // resume user event 1
    resume(eventInstance1);
    assertHistoricState(milestoneId, AVAILABLE);
    assertHistoricState(userEventId1, AVAILABLE);
    assertHistoricState(userEventId2, SUSPENDED);
    assertStateQuery(AVAILABLE, AVAILABLE, SUSPENDED);

    // when user event 1 is terminated
    terminate(eventInstance1);

    // then user event 1 is terminated and milestone is completed caused by its entryCriteria
    assertHistoricState(milestoneId, COMPLETED);
    assertHistoricState(userEventId1, TERMINATED);
    assertHistoricState(userEventId2, SUSPENDED);
    assertStateQuery(COMPLETED, TERMINATED, SUSPENDED);

    // when the case instance is terminated
    terminate(caseInstanceId);

    // then user event 2 is terminated
    assertHistoricState(milestoneId, COMPLETED);
    assertHistoricState(userEventId1, TERMINATED);
    assertHistoricState(userEventId2, TERMINATED);
    assertStateQuery(COMPLETED, TERMINATED, TERMINATED);
  }

  @Deployment
  public void testHistoricCaseActivityInstanceDates() {
    String taskId1 = "PI_HumanTask_1";
    String taskId2 = "PI_HumanTask_2";
    String taskId3 = "PI_HumanTask_3";
    String eventId1 = "PI_UserEvent_1";
    String eventId2 = "PI_UserEvent_2";
    String eventId3 = "PI_UserEvent_3";

    // create test dates
    long duration = 72 * 3600 * 1000;
    Date created = ClockUtil.getCurrentTime();
    Date ended = new Date(created.getTime() + duration);

    ClockUtil.setCurrentTime(created);
    String caseInstanceId = createCaseInstance().getId();
    String taskInstance1 = queryCaseExecutionByActivityId(taskId1).getId();
    String taskInstance2 = queryCaseExecutionByActivityId(taskId2).getId();
    String taskInstance3 = queryCaseExecutionByActivityId(taskId3).getId();
    String eventInstance1 = queryCaseExecutionByActivityId(eventId1).getId();
    String eventInstance2 = queryCaseExecutionByActivityId(eventId2).getId();
    String eventInstance3 = queryCaseExecutionByActivityId(eventId3).getId();

    // assert create time of all historic instances
    assertHistoricCreateTime(taskId1, created);
    assertHistoricCreateTime(taskId2, created);
    assertHistoricCreateTime(eventId1, created);
    assertHistoricCreateTime(eventId2, created);

    // complete human task 1
    manualStart(taskInstance1);
    ClockUtil.setCurrentTime(ended);
    complete(taskInstance1);

    // assert end time of human task 1
    assertHistoricEndTime(taskId1, ended);
    assertHistoricDuration(taskId1, duration);

    // complete user event 1
    ClockUtil.setCurrentTime(ended);
    occur(eventInstance1);

    // assert end time of user event 1
    assertHistoricEndTime(eventId1, ended);
    assertHistoricDuration(eventId1, duration);

    // terminate human task 2
    manualStart(taskInstance2);
    ClockUtil.setCurrentTime(ended);
    terminate(taskInstance2);

    // assert end time of human task 2
    assertHistoricEndTime(taskId2, ended);
    assertHistoricDuration(taskId2, duration);

    // terminate user event 2
    ClockUtil.setCurrentTime(ended);
    terminate(eventInstance2);

    // assert end time of user event 2
    assertHistoricEndTime(eventId2, ended);
    assertHistoricDuration(eventId2, duration);

    // disable human task 3 and suspend user event 3
    disable(taskInstance3);
    suspend(eventInstance3);

    // when terminate case instance
    ClockUtil.setCurrentTime(ended);
    terminate(caseInstanceId);

    // then human task 3 and user event 3 should be terminated and a end time is set
    assertHistoricEndTime(taskId3, ended);
    assertHistoricEndTime(eventId3, ended);
    assertHistoricDuration(taskId3, duration);
    assertHistoricDuration(eventId3, duration);

    // test queries
    Date beforeCreate = new Date(created.getTime() - 3600 * 1000);
    Date afterEnd = new Date(ended.getTime() + 3600 * 1000);

    assertCount(6, historicQuery().createdAfter(beforeCreate));
    assertCount(0, historicQuery().createdAfter(ended));

    assertCount(0, historicQuery().createdBefore(beforeCreate));
    assertCount(6, historicQuery().createdBefore(ended));

    assertCount(6, historicQuery().endedAfter(created));
    assertCount(0, historicQuery().endedAfter(afterEnd));

    assertCount(0, historicQuery().endedBefore(created));
    assertCount(6, historicQuery().endedBefore(afterEnd));
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/cmmn/oneTaskCase.cmmn"})
  public void testHistoricCaseActivityTaskId() {
    String taskId = "PI_HumanTask_1";

    createCaseInstance();

    // as long as the human task was not started there should be no task id set
    assertCount(0, taskService.createTaskQuery());
    HistoricCaseActivityInstance historicInstance = queryHistoricActivityCaseInstance(taskId);
    assertNull(historicInstance.getTaskId());

    // start human task manually to create task instance
    CaseExecution humanTask = queryCaseExecutionByActivityId(taskId);
    manualStart(humanTask.getId());

    // there should exist a single task
    Task task = taskService.createTaskQuery().singleResult();
    assertNotNull(task);

    // check that the task id was correctly set
    historicInstance = queryHistoricActivityCaseInstance(taskId);
    assertEquals(task.getId(), historicInstance.getTaskId());

    // complete task
    taskService.complete(task.getId());

    // check that the task id is still set
    assertCount(0, taskService.createTaskQuery());
    historicInstance = queryHistoricActivityCaseInstance(taskId);
    assertEquals(task.getId(), historicInstance.getTaskId());
  }

  @Deployment(resources={
    "org/camunda/bpm/engine/test/api/cmmn/oneProcessTaskCase.cmmn",
    "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml"
  })
  public void testHistoricCaseActivityCalledProcessInstanceId() {
    String taskId = "PI_ProcessTask_1";

    createCaseInstanceByKey("oneProcessTaskCase").getId();

    // as long as the process task is not activated there should be no process instance
    assertCount(0, runtimeService.createProcessInstanceQuery());

    HistoricCaseActivityInstance historicInstance = queryHistoricActivityCaseInstance(taskId);
    assertNull(historicInstance.getCalledProcessInstanceId());

    // start process task manually to create case instance
    CaseExecution processTask = queryCaseExecutionByActivityId(taskId);
    manualStart(processTask.getId());

    // there should exist a new process instance
    ProcessInstance calledProcessInstance = runtimeService.createProcessInstanceQuery().singleResult();
    assertNotNull(calledProcessInstance);

    // check that the called process instance id was correctly set
    historicInstance = queryHistoricActivityCaseInstance(taskId);
    assertEquals(calledProcessInstance.getId(), historicInstance.getCalledProcessInstanceId());

    // complete task and thereby the process instance
    Task task = taskService.createTaskQuery().singleResult();
    taskService.complete(task.getId());

    // check that the task id is still set
    assertCount(0, runtimeService.createProcessInstanceQuery());
    historicInstance = queryHistoricActivityCaseInstance(taskId);
    assertEquals(calledProcessInstance.getId(), historicInstance.getCalledProcessInstanceId());
  }

  @Deployment(resources = {
    "org/camunda/bpm/engine/test/api/cmmn/oneCaseTaskCase.cmmn",
    "org/camunda/bpm/engine/test/api/cmmn/oneTaskCase.cmmn"
  })
  public void testHistoricCaseActivityCalledCaseInstanceId() {
    String taskId = "PI_CaseTask_1";

    String calledCaseId = "oneTaskCase";
    String calledTaskId = "PI_HumanTask_1";

    createCaseInstanceByKey("oneCaseTaskCase").getId();

    // as long as the case task is not activated there should be no other case instance
    assertCount(0, caseService.createCaseInstanceQuery().caseDefinitionKey(calledCaseId));

    HistoricCaseActivityInstance historicInstance = queryHistoricActivityCaseInstance(taskId);
    assertNull(historicInstance.getCalledCaseInstanceId());

    // start case task manually to create case instance
    CaseExecution caseTask = queryCaseExecutionByActivityId(taskId);
    manualStart(caseTask.getId());

    // there should exist a new case instance
    CaseInstance calledCaseInstance = caseService.createCaseInstanceQuery().caseDefinitionKey(calledCaseId).singleResult();
    assertNotNull(calledCaseInstance);

    // check that the called case instance id was correctly set
    historicInstance = queryHistoricActivityCaseInstance(taskId);
    assertEquals(calledCaseInstance.getId(), historicInstance.getCalledCaseInstanceId());

    // disable task to complete called case instance and close it
    CaseExecution calledTask = queryCaseExecutionByActivityId(calledTaskId);
    disable(calledTask.getId());
    close(calledCaseInstance.getId());

    // check that the called case instance id is still set
    assertCount(0, caseService.createCaseInstanceQuery().caseDefinitionKey(calledCaseId));
    historicInstance = queryHistoricActivityCaseInstance(taskId);
    assertEquals(calledCaseInstance.getId(), historicInstance.getCalledCaseInstanceId());
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/cmmn/oneTaskAndOneStageCase.cmmn"})
  public void testHistoricCaseActivityQuery() {
    String stageId = "PI_Stage_1";
    String stageName = "A HumanTask";
    String taskId = "PI_HumanTask_1";
    String taskName = "A HumanTask";

    String caseInstanceId = createCaseInstance().getId();

    CaseExecution stageExecution = queryCaseExecutionByActivityId(stageId);
    CaseExecution taskExecution = queryCaseExecutionByActivityId(taskId);

    assertCount(1, historicQuery().caseActivityInstanceId(stageExecution.getId()));
    assertCount(1, historicQuery().caseActivityInstanceId(taskExecution.getId()));

    assertCount(2, historicQuery().caseInstanceId(caseInstanceId));
    assertCount(2, historicQuery().caseDefinitionId(stageExecution.getCaseDefinitionId()));

    assertCount(1, historicQuery().caseExecutionId(stageExecution.getId()));
    assertCount(1, historicQuery().caseExecutionId(taskExecution.getId()));

    assertCount(1, historicQuery().caseActivityId(stageId));
    assertCount(1, historicQuery().caseActivityId(taskId));

    assertCount(1, historicQuery().caseActivityName(stageName));
    assertCount(1, historicQuery().caseActivityName(taskName));
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/cmmn/oneTaskCase.cmmn"})
  public void testQueryPaging() {
    createCaseInstance();
    createCaseInstance();
    createCaseInstance();
    createCaseInstance();

    assertEquals(3, historicQuery().listPage(0, 3).size());
    assertEquals(2, historicQuery().listPage(2, 2).size());
    assertEquals(1, historicQuery().listPage(3, 2).size());
  }

  @Deployment(resources = {
    "org/camunda/bpm/engine/test/api/cmmn/oneTaskCase.cmmn",
    "org/camunda/bpm/engine/test/api/cmmn/twoTaskCase.cmmn"
  })
  public void testQuerySorting() {
    String taskId1 = "PI_HumanTask_1";
    String taskId2 = "PI_HumanTask_2";

    String oneTaskCaseId = createCaseInstanceByKey("oneTaskCase").getId();
    String twoTaskCaseId = createCaseInstanceByKey("twoTaskCase").getId();

    CaseExecution task1 = caseService.createCaseExecutionQuery().caseInstanceId(oneTaskCaseId).activityId(taskId1).singleResult();
    CaseExecution task2 = caseService.createCaseExecutionQuery().caseInstanceId(twoTaskCaseId).activityId(taskId1).singleResult();
    CaseExecution task3 = caseService.createCaseExecutionQuery().caseInstanceId(twoTaskCaseId).activityId(taskId2).singleResult();

    // sort by historic case activity instance ids
    assertQuerySorting("id", historicQuery().orderByHistoricCaseActivityInstanceId(),
      task1.getId(), task2.getId(), task3.getId());

    // sort by case instance ids
    assertQuerySorting("caseInstanceId", historicQuery().orderByCaseInstanceId(),
      oneTaskCaseId, twoTaskCaseId, twoTaskCaseId);

    // sort by case execution ids
    assertQuerySorting("caseExecutionId", historicQuery().orderByCaseExecutionId(),
      task1.getId(), task2.getId(), task3.getId());

    // sort by case activity ids
    assertQuerySorting("caseActivityId", historicQuery().orderByCaseActivityId(),
      taskId1, taskId1, taskId2);

    // sort by case activity names
    assertQuerySorting("caseActivityName", historicQuery().orderByCaseActivityName(),
      "A HumanTask", "A HumanTask", "Another HumanTask");

    // sort by case definition ids
    assertQuerySorting("caseDefinitionId", historicQuery().orderByCaseDefinitionId(),
      task1.getCaseDefinitionId(), task2.getCaseDefinitionId(), task3.getCaseDefinitionId());

    // manually start tasks to be able to complete them
    manualStart(task1.getId());
    manualStart(task2.getId());
    manualStart(task3.getId());

    // complete tasks to set end time and duration
    for (Task task : taskService.createTaskQuery().list()) {
      taskService.complete(task.getId());
    }

    HistoricCaseActivityInstanceQuery query = historyService.createHistoricCaseActivityInstanceQuery();
    HistoricCaseActivityInstance historicTask1 = query.caseInstanceId(oneTaskCaseId).caseActivityId(taskId1).singleResult();
    HistoricCaseActivityInstance historicTask2 = query.caseInstanceId(twoTaskCaseId).caseActivityId(taskId1).singleResult();
    HistoricCaseActivityInstance historicTask3 = query.caseInstanceId(twoTaskCaseId).caseActivityId(taskId2).singleResult();

    // sort by create times
    assertQuerySorting("createTime", historicQuery().orderByHistoricCaseActivityInstanceCreateTime(),
      historicTask1.getCreateTime(), historicTask2.getCreateTime(), historicTask3.getCreateTime());

    // sort by end times
    assertQuerySorting("endTime", historicQuery().orderByHistoricCaseActivityInstanceEndTime(),
      historicTask1.getEndTime(), historicTask2.getEndTime(), historicTask3.getEndTime());

    // sort by durations times
    assertQuerySorting("durationInMillis", historicQuery().orderByHistoricCaseActivityInstanceDuration(),
      historicTask1.getDurationInMillis(), historicTask2.getDurationInMillis(), historicTask3.getDurationInMillis());
  }

  public void testInvalidSorting() {
    try {
      historicQuery().asc();
      fail("Exception expected");
    }
    catch (ProcessEngineException e) {
      // expected
    }

    try {
      historicQuery().desc();
      fail("Exception expected");
    }
    catch (ProcessEngineException e) {
      // expected
    }

    try {
      historicQuery().orderByHistoricCaseActivityInstanceId().count();
      fail("Exception expected");
    }
    catch (ProcessEngineException e) {
      // expected
    }
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/cmmn/oneTaskCase.cmmn"})
  public void testNativeQuery() {
    createCaseInstance();
    createCaseInstance();
    createCaseInstance();
    createCaseInstance();

    String instanceId = caseService.createCaseExecutionQuery().activityId("PI_HumanTask_1").list().get(0).getId();

    String tableName = managementService.getTableName(HistoricCaseActivityInstance.class);

    assertEquals("ACT_HI_CASEACTINST", tableName);
    assertEquals(tableName, managementService.getTableName(HistoricCaseActivityInstanceEntity.class));

    assertEquals(4, historyService.createNativeHistoricCaseActivityInstanceQuery().sql("SELECT * FROM " + tableName).list().size());
    assertEquals(4, historyService.createNativeHistoricCaseActivityInstanceQuery().sql("SELECT count(*) FROM " + tableName).count());

    assertEquals(16, historyService.createNativeHistoricCaseActivityInstanceQuery().sql("SELECT count(*) FROM " + tableName + " H1, " + tableName + " H2").count());

    // select with distinct
    assertEquals(4, historyService.createNativeHistoricCaseActivityInstanceQuery().sql("SELECT DISTINCT * FROM " + tableName).list().size());

    assertEquals(1, historyService.createNativeHistoricCaseActivityInstanceQuery().sql("SELECT count(*) FROM " + tableName + " H WHERE H.ID_ = '" + instanceId + "'").count());
    assertEquals(1, historyService.createNativeHistoricCaseActivityInstanceQuery().sql("SELECT * FROM " + tableName + " H WHERE H.ID_ = '" + instanceId + "'").list().size());

    // use parameters
    assertEquals(1, historyService.createNativeHistoricCaseActivityInstanceQuery().sql("SELECT count(*) FROM " + tableName + " H WHERE H.ID_ = #{caseActivityInstanceId}").parameter("caseActivityInstanceId", instanceId).count());
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/cmmn/oneTaskCase.cmmn"})
  public void testNativeQueryPaging() {
    createCaseInstance();
    createCaseInstance();
    createCaseInstance();
    createCaseInstance();

    String tableName = managementService.getTableName(HistoricCaseActivityInstance.class);
    assertEquals(3, historyService.createNativeHistoricCaseActivityInstanceQuery().sql("SELECT * FROM " + tableName).listPage(0, 3).size());
    assertEquals(2, historyService.createNativeHistoricCaseActivityInstanceQuery().sql("SELECT * FROM " + tableName).listPage(2, 2).size());
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/cmmn/oneTaskCase.cmmn"})
  public void testDeleteHistoricCaseActivityInstance() {
    CaseInstance caseInstance = createCaseInstance();

    HistoricCaseActivityInstance historicInstance = historicQuery().singleResult();
    assertNotNull(historicInstance);

    // disable human task to complete case
    disable(historicInstance.getId());
    // close case to be able to delete historic case instance
    close(caseInstance.getId());
    // delete historic case instance
    historyService.deleteHistoricCaseInstance(caseInstance.getId());

    assertCount(0, historicQuery());
  }

  @Deployment
  public void testNonBlockingHumanTask() {
    CaseInstance caseInstance = createCaseInstance();
    assertNotNull(caseInstance);
  }

  protected HistoricCaseActivityInstanceQuery historicQuery() {
    return historyService.createHistoricCaseActivityInstanceQuery();
  }

  protected HistoricCaseActivityInstance queryHistoricActivityCaseInstance(String activityId) {
    HistoricCaseActivityInstance historicActivityInstance = historicQuery()
      .caseActivityId(activityId)
      .singleResult();
    assertNotNull("No historic activity instance found for activity id: " + activityId, historicActivityInstance);
    return historicActivityInstance;
  }

  protected void assertHistoricState(String activityId, CaseExecutionState expectedState) {
    HistoricCaseActivityInstanceEventEntity historicActivityInstance = (HistoricCaseActivityInstanceEventEntity) queryHistoricActivityCaseInstance(activityId);
    int actualStateCode = historicActivityInstance.getCaseActivityInstanceState();
    CaseExecutionState actualState = CaseExecutionState.CaseExecutionStateImpl.getStateForCode(actualStateCode);
    assertEquals("The state of historic case activity '" + activityId + "' wasn't as expected", expectedState, actualState);
  }

  protected void assertHistoricCreateTime(String activityId, Date expectedCreateTime) {
    HistoricCaseActivityInstance historicActivityInstance = queryHistoricActivityCaseInstance(activityId);
    Date actualCreateTime = historicActivityInstance.getCreateTime();
    assertSimilarDate(expectedCreateTime, actualCreateTime);
  }

  protected void assertHistoricEndTime(String activityId, Date expectedEndTime) {
    HistoricCaseActivityInstance historicActivityInstance = queryHistoricActivityCaseInstance(activityId);
    Date actualEndTime = historicActivityInstance.getEndTime();
    assertSimilarDate(expectedEndTime, actualEndTime);
  }

  protected void assertSimilarDate(Date expectedDate, Date actualDate) {
    long difference = Math.abs(expectedDate.getTime() - actualDate.getTime());
    // assert that the dates don't differ more than a second
    assertTrue(difference < 1000);
  }

  protected void assertHistoricDuration(String activityId, long expectedDuration) {
    Long actualDuration = queryHistoricActivityCaseInstance(activityId).getDurationInMillis();
    assertNotNull(actualDuration);
    // test that duration is as expected with a maximal difference of one second
    assertTrue(actualDuration >= expectedDuration);
    assertTrue(actualDuration < expectedDuration + 1000);
  }

  protected void assertCount(long count, Query<?, ?> historicQuery) {
    assertEquals(count, historicQuery.count());
  }

  protected void assertStateQuery(CaseExecutionState... states) {
    CaseExecutionStateCountMap stateCounts = new CaseExecutionStateCountMap();

    if (states != null) {
      for (CaseExecutionState state : states) {
        stateCounts.put(state, stateCounts.get(state) + 1);
      }
    }

    assertCount(stateCounts.count(), historicQuery());
    assertCount(stateCounts.unfinished(), historicQuery().notEnded());
    assertCount(stateCounts.finished(), historicQuery().ended());

    assertCount(stateCounts.get(ACTIVE), historicQuery().active());
    assertCount(stateCounts.get(AVAILABLE), historicQuery().available());
    assertCount(stateCounts.get(COMPLETED), historicQuery().completed());
    assertCount(stateCounts.get(DISABLED), historicQuery().disabled());
    assertCount(stateCounts.get(ENABLED), historicQuery().enabled());
    assertCount(stateCounts.get(TERMINATED), historicQuery().terminated());
  }

  protected class CaseExecutionStateCountMap extends HashMap<CaseExecutionState, Long> {

    private static final long serialVersionUID = 1L;

    public final Collection<CaseExecutionState> ALL_STATES = CaseExecutionState.CASE_EXECUTION_STATES.values();
    public final Collection<CaseExecutionState> ENDED_STATES = Arrays.asList(COMPLETED, TERMINATED);
    public final Collection<CaseExecutionState> NOT_ENDED_STATES;

    public CaseExecutionStateCountMap() {
      NOT_ENDED_STATES = new ArrayList<CaseExecutionState>(ALL_STATES);
      NOT_ENDED_STATES.removeAll(ENDED_STATES);
    }

    public Long get(CaseExecutionState state) {
      return state != null && containsKey(state) ? super.get(state) : 0;
    }

    public Long count() {
      return count(ALL_STATES);
    }

    public Long finished() {
      return count(ENDED_STATES);
    }

    public Long unfinished() {
      return count(NOT_ENDED_STATES);
    }

    public Long count(Collection<CaseExecutionState> states) {
      long count = 0;
      for (CaseExecutionState state : states) {
        count += get(state);
      }
      return count;
    }

  }

  @SuppressWarnings({ "rawtypes", "unchecked" })
  protected void assertQuerySorting(String property, Query<?, ?> query, Comparable... items) {
    AbstractQuery<?, ?> queryImpl = (AbstractQuery<?, ?>) query;

    // save order property to later reverse ordering
    QueryProperty orderProperty = queryImpl.getOrderProperty();

    List<? extends Comparable> sortedList = Arrays.asList(items);
    Collections.sort(sortedList);

    List<Matcher<Object>> matchers = new ArrayList<Matcher<Object>>();
    for (Comparable comparable : sortedList) {
      matchers.add(hasProperty(property, equalTo(comparable)));
    }

    List<?> instances = query.asc().list();
    assertEquals(sortedList.size(), instances.size());
    assertThat(instances, contains(matchers.toArray(new Matcher[matchers.size()])));

    // reverse ordering
    queryImpl.setOrderBy(null);
    queryImpl.orderBy(orderProperty);

    // reverse matchers
    Collections.reverse(matchers);

    instances = query.desc().list();
    assertEquals(sortedList.size(), instances.size());
    assertThat(instances, contains(matchers.toArray(new Matcher[matchers.size()])));
  }

}
TOP

Related Classes of org.camunda.bpm.engine.test.history.HistoricCaseActivityInstanceTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.