/** * @test * @depends it_can_be_started_with_a_message_and_provides_next_commands */ public function it_can_be_continued_with_a_chapter_log_message_and_finishes_if_all_chapter_templates_are_handled(array $storyAndCommand) { /** @var $story Story */ /** @var $command Message */ list($story, $command) = $storyAndCommand; $fileWasProcessed = new FileWasProcessed(); $chapterNumber = ChapterNumber::fromString($command->metadata()['prooph_done_story_chapter']); $fileWasProcessed = $fileWasProcessed->withAddedMetadata('prooph_done_story_chapter', $chapterNumber->toString()); $messageConverter = new NoOpMessageConverter(); $story->continueWith($fileWasProcessed, $this->getTestChapterTemplates(), $messageConverter, new FQCNMessageFactory()); $events = $this->popRecordedEvents($story); $this->assertEquals(3, count($events)); /** @var $chapterMessageWasReceived Story\Event\ChapterMessageWasReceived */ $chapterMessageWasReceived = $events[0]; $this->assertInstanceOf(Story\Event\ChapterMessageWasReceived::class, $chapterMessageWasReceived); $fileWasProcessedData = $messageConverter->convertToArray($fileWasProcessed); $this->assertEquals($fileWasProcessedData, $chapterMessageWasReceived->causationMessage()); $this->assertTrue($chapterNumber->equals($chapterMessageWasReceived->chapterStatus()->chapterNumber())); $this->assertEquals('File Processor', $chapterMessageWasReceived->chapterStatus()->chapterName()->toString()); $this->assertEquals(Story\ChapterStatus::STATUS_RUNNING, $chapterMessageWasReceived->chapterStatus()->status()); /** @var $chapterWasDone Story\Event\ChapterWasDone */ $chapterWasDone = $events[1]; $this->assertInstanceOf(Story\Event\ChapterWasDone::class, $chapterWasDone); $this->assertEquals($fileWasProcessedData, $chapterWasDone->causationMessage()); $this->assertTrue($chapterNumber->equals($chapterWasDone->chapterStatus()->chapterNumber())); $this->assertEquals('File Processor', $chapterWasDone->chapterStatus()->chapterName()->toString()); $this->assertEquals(Story\ChapterStatus::STATUS_DONE, $chapterWasDone->chapterStatus()->status()); /** @var $storyWasDone Story\Event\StoryWasDone */ $storyWasDone = $events[2]; $this->assertInstanceOf(Story\Event\StoryWasDone::class, $storyWasDone); $this->assertTrue($chapterNumber->storyId()->equals($storyWasDone->storyId())); $this->assertEquals('Test Story', $storyWasDone->storyName()->toString()); }
/** * @param Message $message * @throws Exception\Story */ public function __invoke(Message $message) { if ($this->isStartMessage($message)) { $story = Story::start($this->storyName, $message, $this->chapterTemplates, $this->messageConverter); $this->storyLog->add($story); } else { $chapterNumber = ChapterNumber::fromString($message->metadata()[Metadata::STORY_CHAPTER]); $story = $this->storyLog->get($chapterNumber->storyId()); if (null === $story) { throw Exception\Story::withIdCannotBeFound($chapterNumber->storyId()); } $story->continueWith($message, $this->chapterTemplates, $this->messageConverter, $this->messageFactory); } foreach ($story->getNextCommands() as $command) { $this->commandBus->delayDispatch($command); } }
/** * @test */ public function it_starts_a_new_chapter_by_providing_the_chapter_command() { $fileWasUploaded = new FileWasUploaded(); $startCondition = $this->prophesize(MessageCondition::class); $startCondition->isTrueFor($fileWasUploaded)->willReturn(true); $isDoneCondition = $this->prophesize(MessageCondition::class); $payloadGenerator = $this->prophesize(PayloadGenerator::class); $payloadGenerator->__invoke(Argument::any(), Argument::any(), Argument::any())->will(function ($args) { list($previousMessage, $payload, $metadata) = $args; $payload['filename'] = $previousMessage->payload()['filename']; }); $commandTemplate = new MessageTemplate(ProcessFile::class, new FQCNMessageFactory(), [], [], $payloadGenerator->reveal()); $chapterTemplate = new ChapterTemplate(ChapterName::fromString('File Processor'), $commandTemplate, $startCondition->reveal(), $isDoneCondition->reveal()); $storyId = StoryId::generateNew(); $chapterNumber = ChapterNumber::withNumber($storyId, 2); $chapterCommand = $chapterTemplate->startChapter(StoryName::fromString('Test Story'), $chapterNumber, $fileWasUploaded); $this->assertInstanceOf(ProcessFile::class, $chapterCommand); $this->assertEquals('some-file.csv', $chapterCommand->payload()['filename']); $this->assertEquals($chapterNumber->toString(), $chapterCommand->metadata()[Metadata::STORY_CHAPTER]); $this->assertEquals('Test Story', $chapterCommand->metadata()[Metadata::STORY_NAME]); }
/** * @param ChapterNumber $chapterNumber * @return ChapterStatus */ public static function forChapterNumberCannotBeFound(ChapterNumber $chapterNumber) { return new self(sprintf('Chapter status for chapter number %s cannot be found', $chapterNumber->toString())); }
/** * @return \Prooph\Done\Shared\ChapterNumber */ private function getChapterNumber() { return ChapterNumber::first(StoryId::generateNew()); }
/** * @param array $payload * @return ChapterStatus */ private static function payloadToChapterStatus(array $payload) { return ChapterStatus::fromHistoryStatus(ChapterName::fromString($payload['chapter_name']), ChapterNumber::fromString($payload['chapter_number']), $payload['status'], $payload['retry_count'], $payload['retry_limit']); }
/** * @param StoryName $storyName * @param ChapterNumber $chapterNumber * @param Message $previousMessage * @return Message */ public function startChapter(StoryName $storyName, ChapterNumber $chapterNumber, Message $previousMessage) { $command = $this->chapterCommandTemplate->createMessageFromPreviousMessage($previousMessage); $command = $command->withAddedMetadata(Metadata::STORY_CHAPTER, $chapterNumber->toString()); return $command->withAddedMetadata(Metadata::STORY_NAME, $storyName->toString()); }
/** * @param ChapterNumber $chapterNumber * @return Story */ public static function hasNoStartMessageLoggedForChapterNumber(ChapterNumber $chapterNumber) { return new self(sprintf('Story %s has no start message logged for chapter number %d', $chapterNumber->storyId()->toString(), $chapterNumber->number())); }
/** * @param ChapterNumber $chapterNumber * @param MessageFactory $messageFactory * @return Message * @throws Exception\Story */ private function getOriginalStartMessageForChapterNumber(ChapterNumber $chapterNumber, MessageFactory $messageFactory) { if (!isset($this->chapterNumberStartMessageMap[$chapterNumber->toString()])) { throw Exception\Story::hasNoStartMessageLoggedForChapterNumber($chapterNumber); } $messageData = $this->chapterNumberStartMessageMap[$chapterNumber->toString()]; return $messageFactory->createMessageFromArray($messageData['message_name'], $messageData); }