/** * Test Remove method. */ public function testRemove() { $this->given($repository = $this->createRepository())->and($post = PostEventSourcedFactory::create($this->faker->sentence, $this->faker->paragraph))->and($post->changeTitle($this->faker->sentence))->when($repository->persist($post))->then()->object($repository->get($post->id()))->isEqualTo($post)->and()->when($repository->remove($post))->then()->exception(function () use($repository, $post) { $repository->get($post->id()); })->isInstanceOf(\RuntimeException::class); $this->given($repository = $this->createRepository())->and($post = new Post(PostId::fromNative(md5(rand())), $this->faker->sentence, $this->faker->paragraph))->then()->exception(function () use($repository, $post) { $repository->remove($post); })->isInstanceOf(\InvalidArgumentException::class); $this->given($repository = $this->createRepository())->and($post = PostEventSourcedFactory::create($this->faker->sentence, $this->faker->paragraph))->and($repository->persist($post))->and($preRemoveSubscriber = new PreRemoveSubscriber(42))->and($postRemoveSubscriber = new PostRemoveSubscriber())->and(DomainEventPublisher::subscribe($preRemoveSubscriber))->and(DomainEventPublisher::subscribe($postRemoveSubscriber))->when($repository->remove($post))->then()->integer($post->version()->patch())->isEqualTo(21); }
/** * Test Events method. */ public function testEvents() { $this->given($postId = PostId::fromNative(md5(rand())))->and($eventStream = new EventStream('posts', $postId, []))->then()->array($eventStream->events())->isEmpty(); $this->given($postId = PostId::fromNative(md5(rand())))->and($eventStream = new EventStream('posts', $postId, [new PostWasCreated($postId, 'foo', 'bar')]))->then()->array($eventStream->events())->hasSize(1); $this->given($postId = PostId::fromNative(md5(rand())))->then()->exception(function () use($postId) { new EventStream('posts', $postId, ['bar']); })->isInstanceOf(\InvalidArgumentException::class); $this->given($postId = PostId::fromNative(md5(rand())))->then()->exception(function () use($postId) { new EventStream('posts', $postId, [new PostWasCreated(PostId::fromNative(md5(rand())), 'foo', 'bar')]); })->isInstanceOf(\InvalidArgumentException::class); }
/** * Test migrate method. */ public function testMigrate() { $this->migrationsDirectory = __DIR__ . '/../../Fixtures/Migrations'; require_once __DIR__ . '/../../Fixtures/BlogEventSourced.php'; // simulate an application and aggregate version state $currentApplicationVersion = Version::fromString('0.1.0'); $aggregateVersion = Version::fromString('0.1.0'); VersionManager::setCurrentApplicationVersion($currentApplicationVersion); VersionManager::persistVersionOfClass(PostEventSourced::class, $aggregateVersion); VersionManager::persistVersionOfClass(\BlogEventSourced::class, $aggregateVersion); // creating migration store $aggregates = [PostEventSourced::class, \BlogEventSourced::class]; $migratorStore = new InMemoryMigrationStore(); $migratorStore->persist(new Migration($aggregates, $aggregateVersion, new \DateTime())); // creating event store $eventStore = new InMemoryEventStore(); // add the event store flow $postId1 = PostId::fromNative(md5(rand())); $postEventStream1 = new EventStream($this->streamName(PostEventSourced::class), $postId1, [new PostWasCreated($postId1, 'Best restaurants in barcelona', 'empty'), new PostTitleWasChanged($postId1, 'Best cuban restaurants in barcelona')]); $postId2 = PostId::fromNative(md5(rand())); $postEventStream2 = new EventStream($this->streamName(PostEventSourced::class), $postId2, [new PostWasCreated($postId2, 'Best things to do with children in barcelona', 'empty'), new PostTitleWasChanged($postId2, 'Things to do with children in barcelona this weekend')]); $eventStore->persist($postEventStream1, $aggregateVersion, $currentApplicationVersion); $eventStore->persist($postEventStream2, $aggregateVersion, $currentApplicationVersion); // fake BlogEventSourced event stream $postId3 = PostId::fromNative(md5(rand())); $postEventStream2 = new EventStream($this->streamName(\BlogEventSourced::class), $postId3, []); $eventStore->persist($postEventStream2, $aggregateVersion, $currentApplicationVersion); // creating snapshot store $snapshotStore = new InMemorySnapshotStore(); // creating the migrator $migrator = new MigratorWithSnapshot($this->getClassMetadataFactory(), $migratorStore, $eventStore, $snapshotStore, $this->migrationsDirectory); $emptyMigrator = new MigratorWithSnapshot($this->getClassMetadataFactory(), $migratorStore, $eventStore, $snapshotStore, __DIR__ . '/../../Fixtures/EmptyMigrations'); $this->given($result = $emptyMigrator->migrate())->then()->boolean($result)->isFalse(); $this->given($status = $migrator->status())->and($nextVersion = $status->nextAvailableVersion())->then()->boolean($migratorStore->hasMigration($nextVersion))->isFalse()->variable($snapshotStore->load('post_event_sourced', $postId1, $aggregateVersion, $currentApplicationVersion))->isNull()->and()->when($result = $migrator->migrate())->and(VersionManager::setCurrentApplicationVersion($migratorStore->getLast()->version()))->then()->boolean($migratorStore->hasMigration($nextVersion))->isTrue()->boolean($result)->isTrue()->variable($snapshotStore->load('post_event_sourced', $postId1, $aggregateVersion, $nextVersion))->isNotNull()->variable($snapshotStore->load('post_event_sourced', $postId2, $aggregateVersion, $nextVersion))->isNotNull()->and()->exception(function () use($migrator) { // because the V1_0_0\BlogEventSourcedMigration class return an invalid stream $migrator->migrate(); })->isInstanceOf(\RuntimeException::class); }
/** * Test RemoveAll method. */ public function testRemoveAll() { $this->given($store = $this->createStore())->and($postId = PostId::fromNative(md5(rand())))->and($aggregateVersion = new Version())->and($applicationVersion = new Version())->then()->exception(function () use($store, $aggregateVersion, $applicationVersion) { $store->removeAll('posts', $aggregateVersion, $applicationVersion); })->isInstanceOf(\RuntimeException::class); $this->given($store = $this->createStore())->and($postId = PostId::fromNative(md5(rand())))->and($postId1 = PostId::fromNative(md5(rand())))->and($eventStream = new EventStream('posts', $postId, [new PostWasCreated($postId, 'foo', 'bar')]))->and($eventStream1 = new EventStream('posts', $postId1, [new PostWasCreated($postId1, 'baz', 'content')]))->and($aggregateVersion = new Version())->and($applicationVersion = new Version())->when($store->persist($eventStream, $aggregateVersion, $applicationVersion))->and($store->persist($eventStream1, $aggregateVersion, $applicationVersion))->then()->array($store->loadAll('posts', $aggregateVersion, $applicationVersion))->hasSize(2)->and()->when($store->removeAll('posts', $aggregateVersion, $applicationVersion))->then()->exception(function () use($store, $aggregateVersion, $applicationVersion) { // because there is no stream entry in the current application store $store->loadAll('posts', $aggregateVersion, $applicationVersion); })->isInstanceOf(\RuntimeException::class)->and()->when($applicationVersion = Version::fromString('2.1.0'))->then()->exception(function () use($store, $aggregateVersion, $applicationVersion) { // because there is application entry in the store $store->removeAll('posts', $aggregateVersion, $applicationVersion); })->isInstanceOf(\RuntimeException::class); }
/** * Test Load method. */ public function testLoad() { $this->given($store = $this->createStore())->and($post = PostEventSourcedFactory::create($this->faker->sentence, $this->faker->paragraph))->and($snapshot = new Snapshot('posts', $post, new \DateTime()))->and($applicationVersion = Version::fromString('1.1.0'))->when($store->persist($snapshot, $applicationVersion))->then()->variable($store->load('blogs', $post->id(), $post->version(), $applicationVersion))->isNull()->variable($store->load('posts', PostId::fromNative(md5(rand())), $post->version(), $applicationVersion))->isNull(); }
/** * @return MigrationsService */ protected function createServiceWithMigrations() { $this->migrationsDirectory = __DIR__ . '/../../../Fixtures/Migrations'; require_once __DIR__ . '/../../../Fixtures/BlogEventSourced.php'; // simulate an application and aggregate version state $currentApplicationVersion = Version::fromString('0.1.0'); VersionManager::setCurrentApplicationVersion($currentApplicationVersion); VersionManager::persistVersionOfClass(PostEventSourced::class, $currentApplicationVersion); VersionManager::persistVersionOfClass(\BlogEventSourced::class, $currentApplicationVersion); // creating migration store $aggregates = [PostEventSourced::class, \BlogEventSourced::class]; $migratorStore = new InMemoryMigrationStore(); $migratorStore->persist(new Migration($aggregates, $currentApplicationVersion, new \DateTime())); // creating event store $eventStore = new InMemoryEventStore(); // add the event store flow $postId1 = PostId::fromNative(md5(rand())); $postEventStream1 = new EventStream($this->streamName(PostEventSourced::class), $postId1, [new PostWasCreated($postId1, 'Best restaurants in barcelona', 'empty'), new PostTitleWasChanged($postId1, 'Best cuban restaurants in barcelona')]); $postId2 = PostId::fromNative(md5(rand())); $postEventStream2 = new EventStream($this->streamName(PostEventSourced::class), $postId2, [new PostWasCreated($postId2, 'Best things to do with children in barcelona', 'empty'), new PostTitleWasChanged($postId2, 'Things to do with children in barcelona this weekend')]); $eventStore->persist($postEventStream1, $currentApplicationVersion, $currentApplicationVersion); $eventStore->persist($postEventStream2, $currentApplicationVersion, $currentApplicationVersion); // fake BlogEventSourced event stream $postId2 = PostId::fromNative(md5(rand())); $postEventStream2 = new EventStream($this->streamName(\BlogEventSourced::class), $postId2, [new PostWasCreated($postId2, 'Blog', 'empty'), new PostTitleWasChanged($postId2, 'new title')]); $eventStore->persist($postEventStream2, $currentApplicationVersion, $currentApplicationVersion); return new MigrationsService(new Migrator($this->getClassMetadataFactory(), $migratorStore, $eventStore, $this->migrationsDirectory)); }
/** * Test equals method. */ public function testEquals() { $this->given($aggregateRoot1 = new Post(PostId::fromNative($this->faker->unique()->uuid()), $this->faker->sentence(), $this->faker->paragraph()))->and($aggregateRoot2 = new Post(PostId::fromNative($this->faker->ean13()), $this->faker->sentence(), $this->faker->paragraph()))->then()->boolean($aggregateRoot1->equals($aggregateRoot1))->isTrue()->boolean($aggregateRoot1->equals($aggregateRoot2))->isFalse(); }
/** * Test Version method. */ public function testVersion() { $this->given($postId = PostId::fromNative(md5(rand())))->when($event = new PostWasCreated($postId, $this->faker->sentence, $this->faker->paragraph))->then()->integer($event->version())->isEqualTo(0)->and()->when($event->setVersion(165))->then()->integer($event->version())->isEqualTo(165); }