/**
   * Test legal workflow combinations.
   *
   * @throws Exception the exception
   */
  @Test
  public void testLegalWorkflowCombinations() throws Exception {

    Logger.getLogger(WorkflowPathStatesQAPathTest.class)
        .info("Testing all possible combinations against legal states...");

    // test empty state
    if (handler.isEmptyWorkflowAllowed()) {
      assertTrue(
          "Empty workflow permitted",
          handler.isWorkflowCombinationInTrackingRecordStates(new WorkflowStatusCombination()));
    } else {
      assertTrue(
          "Empty workflow not permitted",
          !handler.isWorkflowCombinationInTrackingRecordStates(new WorkflowStatusCombination()));
    }

    // test declared states
    for (WorkflowStatusCombination combination : handler.getWorkflowStatusCombinations()) {

      // compute workflow
      getTrackingRecord(combination);

      // validate the tracking record
      assertTrue(handler.validateTrackingRecord(trackingRecord).isValid());
    }
  }
  /**
   * Test illegal workflow status combinations.
   *
   * @throws Exception the exception
   */
  @Test
  public void testIllegalWorkflowStatusCombinations() throws Exception {

    // set of combinations to test
    Set<WorkflowStatusCombination> combinations = new HashSet<>();

    // maximum number to test
    int nResults = 10;

    // random number generator
    Random random = new Random();

    // extract the status values for convenience
    WorkflowStatus[] statuses = WorkflowStatus.values();

    // cycle over possible combinations of records
    for (int nRecords = 1; nRecords <= 4; nRecords++) {

      // maximum calculations for statuses and number of records
      // e.g. 6 statuses, 2 records -> 36 statuses
      int maxResults = statuses.length ^ (nRecords - 1);

      // while combinations less than max results and less than desired results
      while (combinations.size() < nResults && combinations.size() < maxResults) {

        // create a new random combination
        WorkflowStatusCombination combination = new WorkflowStatusCombination();
        for (int i = 0; i < nRecords; i++) {

          combination.addWorkflowStatus(statuses[random.nextInt(statuses.length)]);
        }
        if (!handler.isWorkflowCombinationInTrackingRecordStates(combination)) {
          combinations.add(combination);
        }
      }
    }

    // make sure the number of generated concepts is in desired range
    assertTrue(combinations.size() > 0 && combinations.size() <= nResults);

    // test the combinations
    for (WorkflowStatusCombination combination : combinations) {

      try {
        getTrackingRecord(combination);
      } catch (Exception e) {

        // if this tracking record contains a PUBLISHED or READY_FOR_PUBLICATION
        // record, ignore error, otherwise fail
        if (combination.getWorkflowStatuses().size() == 1
                && combination
                    .getWorkflowStatuses()
                    .keySet()
                    .iterator()
                    .next()
                    .equals(WorkflowStatus.READY_FOR_PUBLICATION)
            || combination
                .getWorkflowStatuses()
                .keySet()
                .iterator()
                .next()
                .equals(WorkflowStatus.PUBLISHED)) {
          // do nothing
        } else {
          fail("Error computing tracking record for combination " + combination.toString());
        }
      }
      assertTrue(!handler.validateTrackingRecord(trackingRecord).isValid());
    }
  }