@Test public void useCasesAreUniquelyIdentifiedByName() { UseCasePart useCasePart = modelBuilder.useCase(USE_CASE); Model model = useCasePart.basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .flow(ALTERNATIVE_FLOW) .step(SYSTEM_DISPLAYS_TEXT_AGAIN).system(displaysConstantText()).build(); assertEquals(1, model.getUseCases().size()); assertEquals(model.findUseCase(USE_CASE), model.getUseCases().iterator().next()); }
@Test public void sameEventTypeReactedTo() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow().anytime() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .flow("Alternative Flow: Could react as well").anytime() .step(CUSTOMER_ENTERS_ALTERNATIVE_TEXT).user(EntersText.class).system(displaysEnteredText()) .build(); modelRunner.run(model); Set<Class<?>> reactToTypes = modelRunner.getReactToTypes(); assertEquals(1, reactToTypes.size()); Class<?> eventTypeReactedTo = reactToTypes.iterator().next(); assertEquals(EntersText.class, eventTypeReactedTo); }
@Test public void throwsExceptionIfFlowIsCreatedTwice() { thrown.expect(ElementAlreadyInModel.class); thrown.expectMessage(ALTERNATIVE_FLOW); modelBuilder .useCase(USE_CASE) .flow(ALTERNATIVE_FLOW) .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .flow(ALTERNATIVE_FLOW); }
@Test public void createsOneStepInAlternativeFlowAndCheckIfItExistsByIndex() { UseCasePart useCasePart = modelBuilder.useCase(USE_CASE); useCasePart.basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()).flow(ALTERNATIVE_FLOW) .step(SYSTEM_DISPLAYS_TEXT_AGAIN).system(displaysConstantText()); List<FlowStep> steps = useCasePart.getUseCase().findFlow(ALTERNATIVE_FLOW).getSteps(); assertEquals(1, steps.size()); assertEquals(SYSTEM_DISPLAYS_TEXT_AGAIN, steps.get(0).getName()); }
@Test public void createsTwoStepsInDifferentFlowsThatBothHaveNoPreviousSteps() { UseCasePart useCasePart = modelBuilder.useCase(USE_CASE); useCasePart .basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .flow(ALTERNATIVE_FLOW) .step(SYSTEM_DISPLAYS_TEXT_AGAIN).system(displaysConstantText()); FlowStep firstUseCaseStep = (FlowStep)useCasePart.getUseCase().findStep(SYSTEM_DISPLAYS_TEXT); FlowStep secondUseCaseStep = (FlowStep)useCasePart.getUseCase().findStep(SYSTEM_DISPLAYS_TEXT_AGAIN); assertFalse(firstUseCaseStep.getPreviousStepInFlow().isPresent()); assertFalse(secondUseCaseStep.getPreviousStepInFlow().isPresent()); }
@Test public void stepThasHasTrueConditionReactsEvenIfOtherStepWouldBePerformedBySystem() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .flow("Alternative Flow: Skipped").condition(() -> false) .step(THIS_STEP_SHOULD_BE_SKIPPED).system(() -> System.out.println("You should not see this!")) .build(); modelRunner.run(model).reactTo(entersText(), entersText()); assertRecordedStepNames(CUSTOMER_ENTERS_TEXT); }
@Test public void doesNotHandleExceptionIfNoExceptionOccurs() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .flow(ALTERNATIVE_FLOW).after(SYSTEM_DISPLAYS_TEXT) .step(SYSTEM_HANDLES_EXCEPTION).on(ArrayIndexOutOfBoundsException.class).system(e -> {}) .build(); modelRunner.run(model); assertRecordedStepNames(SYSTEM_DISPLAYS_TEXT); }
@Test public void doesNotHandleExceptionIfSystemReactionDoesNotThrowException() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .flow(ALTERNATIVE_FLOW).after(SYSTEM_DISPLAYS_TEXT) .step(SYSTEM_HANDLES_EXCEPTION).on(ArrayIndexOutOfBoundsException.class).system(e -> {}) .build(); modelRunner.run(model); assertRecordedStepNames(SYSTEM_DISPLAYS_TEXT); }
@Test public void handlesExceptionAfterSpecificStep() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow() .step(SYSTEM_THROWS_EXCEPTION).system(throwsArrayIndexOutOfBoundsException()) .flow(ALTERNATIVE_FLOW).after(SYSTEM_THROWS_EXCEPTION) .step(SYSTEM_HANDLES_EXCEPTION).on(ArrayIndexOutOfBoundsException.class).system(e -> {}) .build(); modelRunner.run(model); assertEquals(SYSTEM_HANDLES_EXCEPTION, latestStepName()); }
@Test public void reactsToSecondStepAlternativeWhen() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .step(THIS_STEP_SHOULD_BE_SKIPPED).user(EntersText.class).system(throwsRuntimeException()) .flow(ALTERNATIVE_FLOW).condition(() -> CUSTOMER_ENTERS_TEXT.equals(latestStepName())) .step(CUSTOMER_ENTERS_ALTERNATIVE_TEXT).user(EntersText.class).system(displaysEnteredText()) .build(); modelRunner.run(model).reactTo(entersText(), entersAlternativeText()); assertRecordedStepNames(CUSTOMER_ENTERS_TEXT, CUSTOMER_ENTERS_ALTERNATIVE_TEXT); }
@Test public void onlyStepWithTrueConditionReacts() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .flow("Alternative Flow: Skipped").condition(() -> false) .step(THIS_STEP_SHOULD_BE_SKIPPED).user(EntersText.class).system(throwsRuntimeException()) .build(); modelRunner.run(model).reactTo(entersText(), entersText()); assertRecordedStepNames(CUSTOMER_ENTERS_TEXT); }
@Test public void throwsExceptionIfMoreThanOneStepCanReactInSameUseCase() { thrown.expect(MoreThanOneStepCanReact.class); thrown.expectMessage(CUSTOMER_ENTERS_TEXT); thrown.expectMessage(CUSTOMER_ENTERS_ALTERNATIVE_TEXT); Model model = modelBuilder .useCase(USE_CASE) .basicFlow().anytime() .step(CUSTOMER_ENTERS_TEXT).system(displaysConstantText()) .flow(ALTERNATIVE_FLOW).anytime() .step(CUSTOMER_ENTERS_ALTERNATIVE_TEXT).system(displaysConstantText()) .build(); modelRunner.run(model); }
@Test public void reactsToFirstStepAlternativeWhen() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(THIS_STEP_SHOULD_BE_SKIPPED).user(EntersText.class).system(throwsRuntimeException()) .step(THIS_STEP_SHOULD_BE_SKIPPED_AS_WELL).user(EntersText.class).system(throwsRuntimeException()) .flow(ALTERNATIVE_FLOW).condition(this::textIsNotAvailable) .step(CUSTOMER_ENTERS_ALTERNATIVE_TEXT).user(EntersText.class).system(displaysEnteredText()) .build(); modelRunner.run(model).reactTo(entersText()); assertRecordedStepNames(CUSTOMER_ENTERS_ALTERNATIVE_TEXT); }
@Test public void reactsToAlternativeAfterFirstStep() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .step(THIS_STEP_SHOULD_BE_SKIPPED).user(EntersText.class).system(throwsRuntimeException()) .flow(ALTERNATIVE_FLOW).insteadOf(THIS_STEP_SHOULD_BE_SKIPPED) .step(CUSTOMER_ENTERS_ALTERNATIVE_TEXT).user(EntersText.class).system(displaysEnteredText()) .build(); modelRunner.run(model).reactTo(entersText(), entersAlternativeText()); assertRecordedStepNames(CUSTOMER_ENTERS_TEXT, CUSTOMER_ENTERS_ALTERNATIVE_TEXT); }
@Test public void continuesWithoutAlternativeAtFirstStepCalledFromFirstStepOfAlternativeFlowWithoutEvent() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_TEXT_AGAIN).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_NUMBER).user(EntersNumber.class).system(displaysEnteredNumber()) .flow(ALTERNATIVE_FLOW).insteadOf(CUSTOMER_ENTERS_TEXT) .step(CONTINUE).continuesWithoutAlternativeAt(CUSTOMER_ENTERS_TEXT) .build(); modelRunner.run(model).reactTo(entersText(), entersText()); assertRecordedStepNames(CONTINUE, CUSTOMER_ENTERS_TEXT, CUSTOMER_ENTERS_TEXT_AGAIN); }
@Test public void continuesAfterCalledFromFirstStepOfAlternativeFlowWithRightActor() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).as(secondActor).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_TEXT_AGAIN).as(secondActor, customer).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_NUMBER).as(secondActor, customer).user(EntersNumber.class).system(displaysEnteredNumber()) .flow(ALTERNATIVE_FLOW).insteadOf(CUSTOMER_ENTERS_TEXT) .step(CONTINUE).as(customer).continuesAfter(CUSTOMER_ENTERS_TEXT) .build(); modelRunner.as(customer).run(model).reactTo(entersText(), entersNumber()); assertRecordedStepNames(CONTINUE, CUSTOMER_ENTERS_TEXT_AGAIN, CUSTOMER_ENTERS_NUMBER); }
@Test public void continuesAtCalledFromFirstStepOfAlternativeFlowWithRightActor() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).as(secondActor).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_TEXT_AGAIN).as(secondActor, customer).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_NUMBER).as(secondActor, customer).user(EntersNumber.class).system(displaysEnteredNumber()) .flow(ALTERNATIVE_FLOW).insteadOf(CUSTOMER_ENTERS_TEXT) .step(CONTINUE).as(customer).continuesAt(CUSTOMER_ENTERS_TEXT_AGAIN) .build(); modelRunner.as(customer).run(model).reactTo(entersText(), entersNumber()); assertRecordedStepNames(CONTINUE, CUSTOMER_ENTERS_TEXT_AGAIN, CUSTOMER_ENTERS_NUMBER); }
@Test public void continuesAtNotCalledWhenActorIsWrong() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).as(secondActor).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_TEXT_AGAIN).as(secondActor, customer).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_NUMBER).as(secondActor, customer).user(EntersNumber.class).system(displaysEnteredNumber()) .flow(ALTERNATIVE_FLOW).insteadOf(CUSTOMER_ENTERS_TEXT) .step(CONTINUE).as(customer).continuesAt(CUSTOMER_ENTERS_TEXT_AGAIN) .build(); modelRunner.as(secondActor).run(model).reactTo(entersText(), entersText(), entersNumber()); assertRecordedStepNames(CUSTOMER_ENTERS_TEXT, CUSTOMER_ENTERS_TEXT_AGAIN, CUSTOMER_ENTERS_NUMBER); }
@Test public void continuesAfterNotCalledWhenActorIsWrong() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).as(secondActor).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_TEXT_AGAIN).as(secondActor, customer).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_NUMBER).as(secondActor, customer).user(EntersNumber.class).system(displaysEnteredNumber()) .flow(ALTERNATIVE_FLOW).insteadOf(CUSTOMER_ENTERS_TEXT) .step(CONTINUE).as(customer).continuesAfter(CUSTOMER_ENTERS_TEXT) .build(); modelRunner.as(secondActor).run(model).reactTo(entersText(), entersText(), entersNumber()); assertRecordedStepNames(CUSTOMER_ENTERS_TEXT, CUSTOMER_ENTERS_TEXT_AGAIN, CUSTOMER_ENTERS_NUMBER); }
@Test public void continuesWithoutAlternativeAtNotCalledWhenActorIsWrong() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).as(secondActor).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_TEXT_AGAIN).as(secondActor, customer).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_NUMBER).as(secondActor, customer).user(EntersNumber.class).system(displaysEnteredNumber()) .flow(ALTERNATIVE_FLOW).insteadOf(CUSTOMER_ENTERS_TEXT) .step(CONTINUE).as(customer).continuesWithoutAlternativeAt(CUSTOMER_ENTERS_TEXT) .build(); modelRunner.as(secondActor).run(model).reactTo(entersText(), entersText(), entersNumber()); assertRecordedStepNames(CUSTOMER_ENTERS_TEXT, CUSTOMER_ENTERS_TEXT_AGAIN, CUSTOMER_ENTERS_NUMBER); }