SurveyInstanceStateMachine { public SurveyInstanceStatus process(SurveyInstanceAction action, SurveyInstancePermissions permissions, SurveyInstance instance) { for (SurveyInstanceStateTransition possibleTransition: transitions.getOrDefault(current, emptyList())) { boolean isSameAction = possibleTransition.getAction() == action; boolean isAllowedByPredicate = possibleTransition.getPredicate().apply(permissions, instance); if (isSameAction && isAllowedByPredicate) { this.current = possibleTransition.getFutureStatus(); return this.current; } } throw new IllegalArgumentException("You cannot transition from " + current + " with action " + action + " given permissions: " + permissions); } SurveyInstanceStateMachine(SurveyInstanceStatus current, MultiValueMap<SurveyInstanceStatus, SurveyInstanceStateTransition> transitions); SurveyInstanceStatus getCurrent(); List<SurveyInstanceStatus> nextPossibleStatus(SurveyInstancePermissions permissions, SurveyInstance instance); List<SurveyInstanceAction> nextPossibleActions(SurveyInstancePermissions permissions, SurveyInstance instance); SurveyInstanceStatus process(SurveyInstanceAction action, SurveyInstancePermissions permissions, SurveyInstance instance);  }
@Test public void process() { SurveyInstanceStateMachine state = SurveyInstanceStateMachineFactory.simple("NOT_STARTED"); assertEquals(IN_PROGRESS, state.process(SAVING, admin, survey)); assertEquals(COMPLETED, state.process(SUBMITTING, admin, survey)); assertEquals(APPROVED, state.process(APPROVING, admin, survey)); assertEquals(IN_PROGRESS, state.process(REOPENING, admin, survey)); assertEquals(WITHDRAWN, state.process(WITHDRAWING, admin, survey)); assertEquals(IN_PROGRESS, state.process(REOPENING, admin, survey)); assertEquals(COMPLETED, state.process(SUBMITTING, admin, survey)); assertEquals(REJECTED, state.process(REJECTING, admin, survey)); }
@Test public void permissionCheckPasses() { SurveyInstanceStateMachine state = SurveyInstanceStateMachineFactory.simple("NOT_STARTED"); assertEquals(IN_PROGRESS, state.process(SAVING, participant, survey)); assertEquals(COMPLETED, state.process(SUBMITTING, participant, survey)); }
@Test(expected = IllegalArgumentException.class) public void permissionCheckRejects() { SurveyInstanceStateMachine state = SurveyInstanceStateMachineFactory.simple("APPROVED"); assertEquals(IN_PROGRESS, state.process(REOPENING, participant, survey)); state.process(WITHDRAWING, participant, survey); }