public void testGetCaseModelByInvalidId() throws Exception {
    try {
      repositoryService.getCaseModel("invalid");
    } catch (ProcessEngineException e) {
      assertTextPresent("no deployed case definition found with id 'invalid'", e.getMessage());
    }

    try {
      repositoryService.getCaseModel(null);
      fail();
    } catch (NotValidException e) {
      assertTextPresent("caseDefinitionId is null", e.getMessage());
    }
  }
  public void createTask(TaskDto taskDto) {
    ProcessEngine engine = getProcessEngine();
    TaskService taskService = engine.getTaskService();

    Task newTask = taskService.newTask(taskDto.getId());
    taskDto.updateTask(newTask);

    try {
      taskService.saveTask(newTask);

    } catch (NotValidException e) {
      throw new InvalidRequestException(
          Status.BAD_REQUEST, e, "Could not save task: " + e.getMessage());
    }
  }
  /** CAM-4090 */
  @Deployment(resources = NESTED_ASYNC_BEFORE_TASK_PROCESS)
  public void testCancelTransitionInstanceTwiceFailsCase2() {
    // given there are two transition instances in an inner scope
    // and an active activity instance in an outer scope
    ProcessInstance instance =
        runtimeService
            .createProcessInstanceByKey("nestedOneTaskProcess")
            .startBeforeActivity("innerTask")
            .startBeforeActivity("innerTask")
            .execute();

    ActivityInstance tree = runtimeService.getActivityInstance(instance.getId());

    // when i cancel both transition instances
    TransitionInstance[] transitionInstances = tree.getTransitionInstances("innerTask");

    // this test ensures that the replacedBy link of executions is not followed
    // in case the original execution was actually removed/cancelled

    try {
      runtimeService
          .createProcessInstanceModification(instance.getId())
          .cancelTransitionInstance(transitionInstances[0].getId()) // compacts the tree;
          // => execution for transitionInstances[1] is replaced by scope execution
          .startBeforeActivity("innerTask") // expand tree again
          // => scope execution is replaced by a new concurrent execution
          .startBeforeActivity("innerTask")
          .cancelTransitionInstance(transitionInstances[1].getId()) // does not trigger compaction
          .cancelTransitionInstance(transitionInstances[1].getId()) // should fail
          // => execution for transitionInstances[1] should no longer have a replacedBy link
          .execute();
      fail("should not be possible to cancel the first instance twice");
    } catch (NotValidException e) {
      String transitionInstanceId = transitionInstances[1].getId();
      assertTextPresentIgnoreCase(
          "Cannot perform instruction: Cancel transition instance '"
              + transitionInstanceId
              + "'; Transition instance '"
              + transitionInstanceId
              + "' does not exist: transitionInstance is null",
          e.getMessage());
    }
  }