Пример #1
0
        public async Task GivenDraftFeature_WhenPublishingFeatureUpdatedEvent_ThenWePublishTheEvent()
        {
            var createdAlready = new FeatureCreatedEvent {
                Name = "bob",
                Path = "let/me/show/you",
            };

            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(new List <IEvent> {
                createdAlready
            });

            var updated = new FeatureUpdatedEvent {
                Name    = "bob",
                Path    = "let/me/show/you",
                NewName = "bob2",
                NewPath = "let",
            };

            var aggregate = await this
                            .GivenAggregate(reader.Object, client.Object)
                            .WithLoad()();

            await aggregate
            .WhenPublishing(updated)
            .ThenWePublish(client, updated)
            .ThenFeatureIsUpdated(aggregate, updated);
        }
        public async Task GivenNoMatchingArchivedFeatures_WhenLoading_ThenWeThrowFeatureNotFoundException()
        {
            var created = new FeatureCreatedEvent {
                Name = "🦝",
                Path = "let/me/show/you",
            };

            var archived = new FeatureArchivedEvent {
                Name = "bob",
                Path = "let/me/show/you",
            };

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(new List <IEvent> {
                created, archived
            });

            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            await this
            .GivenAggregate(reader.Object, client.Object)
            .WithLoad()
            .ThenExceptionIsThrown <FeatureNotFoundException>();
        }
        public async Task GivenNoMatchingFeatures_WhenLoading_ThenWeDontUpdateTheCreatedEvent()
        {
            var created = new FeatureCreatedEvent {
                Name = "🦝",
                Path = "let/me/show/you",
            };

            var assigned = new StrategyAssignedEvent {
                Name         = "bob",
                Path         = "let/me/show/you",
                StrategyName = StrategyNames.IsOn,
                Settings     = "settings",
            };

            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(new List <IEvent> {
                created, assigned
            });

            await this
            .GivenAggregate(reader.Object, client.Object)
            .WithLoad()
            .ThenExceptionIsThrown <FeatureNotFoundException>();
        }
        public async Task GivenAPublishedFeature_WhenAssigningAStrategy_ThenWeThrow()
        {
            var created = new FeatureCreatedEvent {
                Name = "bob",
                Path = "let/me/show/you",
            };

            var published = new FeaturePublishedEvent {
                Name = created.Name,
                Path = created.Path,
            };

            var assigned = new StrategyAssignedEvent {
                Name         = created.Name,
                Path         = created.Path,
                StrategyName = "yolo",
                Settings     = "settings",
            };

            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(new List <IEvent> {
                created,
                published,
                assigned,
            });

            await this
            .GivenAggregate(reader.Object, client.Object)
            .WithLoad()
            .ThenExceptionIsThrown <FeatureIsNotInDraftException>();
        }
Пример #5
0
        public async Task GivenNoFeatures_WhenPublishingFeatureCreatedEvent_ThenWePublishTheFeature()
        {
            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(Enumerable.Empty <IEvent>());

            var created = new FeatureCreatedEvent {
                Name = "bob",
                Path = "let/me/show/you",
            };

            var aggregate = await this
                            .GivenAggregate(reader.Object, client.Object)
                            .WithLoad()();

            await aggregate
            .WhenPublishing(created)
            .ThenWePublish(client, created);

            aggregate.Features.Select(_ => _.Name).Should()
            .BeEquivalentTo(new List <string> {
                created.Name
            });
        }
Пример #6
0
        public async Task GivenFeaturePublishedBefore_WhenPublishingFeatureUpdatedEvent_ThenWeThrowFeatureWasPublishedBefoeException()
        {
            var createdAlready = new FeatureCreatedEvent {
                Name = "bob",
                Path = "let/me/show/you",
            };
            var publishedAlready = new FeaturePublishedEvent {
                Name        = createdAlready.Name,
                Path        = createdAlready.Path,
                PublishedBy = "moua",
            };
            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(new List <IEvent> {
                createdAlready, publishedAlready
            });

            var updated = new FeatureUpdatedEvent {
                Name    = createdAlready.Name,
                Path    = createdAlready.Path,
                NewName = "bob2",
                NewPath = "let",
            };

            var aggregate = await this
                            .GivenAggregate(reader.Object, client.Object)
                            .WithLoad()();

            await aggregate
            .WhenPublishing(updated)
            .ThenExceptionIsThrown <FeatureIsNotInDraftException>();
        }
        public static EventData ToEventData(this FeatureCreatedEvent featureCreatedEvent, JsonSerializerOptions settings = null !)
        {
            var contentBytes = JsonSerializer.SerializeToUtf8Bytes(featureCreatedEvent, settings);

            return(new EventData(
                       eventId: Uuid.NewUuid(),
                       type: featureCreatedEvent.Type,
                       data: contentBytes
                       ));
        }
        public async Task GivenAMatchingFeatureButNOMatchingStrategy_WhenLoadingStrategyUnassigned_ThenWeChangeNothing()
        {
            var notMe = new FeatureCreatedEvent {
                Name = "🌲",
                Path = "let/me/show/you",
            };

            var created = new FeatureCreatedEvent {
                Name = "bob",
                Path = "let/me/show/you",
            };

            var assigned = new StrategyAssignedEvent {
                Name         = created.Name,
                Path         = created.Path,
                StrategyName = "yolo",
                Settings     = "settings",
            };

            var unassigned = new StrategyUnAssignedEvent {
                Name         = created.Name,
                Path         = created.Path,
                StrategyName = StrategyNames.IsOn,
            };

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(new List <IEvent> {
                created, notMe, assigned, unassigned
            });

            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            var aggregate = await this
                            .GivenAggregate(reader.Object, client.Object)
                            .WithLoad()();

            var features = aggregate.Features.ToList();

            features.Select(_ => _.Name).Should()
            .BeEquivalentTo(new List <string> {
                created.Name, notMe.Name
            });

            features.Where(_ => _.Name == unassigned.Name)
            .SelectMany(_ => _.Strategies.Select(s => s.Name))
            .Should()
            .BeEquivalentTo(new List <string>
            {
                "yolo",
            });
        }
        public async Task GivenAMatchingFeature_WhenPublishingFeatureArchivedEvent_ThenWePublishTheFeature()
        {
            var notMe = new FeatureCreatedEvent {
                Name = "🌲",
                Path = "let/me/show/you",
            };

            var created = new FeatureCreatedEvent {
                Name = "bob",
                Path = "let/me/show/you",
            };

            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(new List <IEvent> {
                created, notMe
            });

            var aggregate = await this
                            .GivenAggregate(reader.Object, client.Object)
                            .WithLoad()();

            var archived = new FeatureArchivedEvent {
                Name = "bob",
                Path = "let/me/show/you",
            };

            await aggregate
            .WhenPublishing(archived)
            .ThenWePublish(client, archived);

            var features = aggregate.Features.ToList();

            features.Select(_ => _.Name).Should()
            .BeEquivalentTo(new List <string> {
                created.Name, notMe.Name
            });
            features.Where(_ => _.Name == archived.Name).Select(_ => _.State)
            .Should()
            .BeEquivalentTo(new List <FeatureState> {
                FeatureState.Archived
            });
            features.Where(_ => _.Name != archived.Name).Select(_ => _.State)
            .Should()
            .BeEquivalentTo(new List <FeatureState> {
                FeatureState.Draft
            });
        }
        public async Task <FeatureDTO> Handle(CreateFeatureCommand message, CancellationToken cancellationToken)
        {
            var feature = new Feature(message.Name, message.Description, message.Price);

            _repository.Add(feature);

            await _repository.UnitOfWork.SaveChangesAsync();

            var featureDTO       = _mapper.Map <FeatureDTO>(feature);
            var integrationEvent = new FeatureCreatedEvent(featureDTO);
            await _integrationEventService.AddAndSaveEventAsync(integrationEvent);

            return(featureDTO);
        }
        public async Task GivenAMatchingFeature_WhenPublishingStrategyAssigned_ThenWePublishTheFeature()
        {
            var notMe = new FeatureCreatedEvent {
                Name = "🌲",
                Path = "let/me/show/you",
            };

            var created = new FeatureCreatedEvent {
                Name = "bob",
                Path = "let/me/show/you",
            };

            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(new List <IEvent> {
                created, notMe
            });

            var assigned = new StrategyAssignedEvent {
                Name         = "bob",
                Path         = "let/me/show/you",
                StrategyName = StrategyNames.IsOn,
                Settings     = "settings",
            };

            var aggregate = await this
                            .GivenAggregate(reader.Object, client.Object)
                            .WithLoad()();

            await aggregate
            .WhenPublishing(assigned)
            .ThenWePublish(client, assigned);

            var features = aggregate.Features.ToList();

            features.Select(_ => _.Name).Should()
            .BeEquivalentTo(new List <string> {
                created.Name, notMe.Name
            });

            features.Where(_ => _.Name == assigned.Name)
            .SelectMany(_ => _.Strategies.Select(s => s.Name))
            .Should()
            .BeEquivalentTo(new List <string> {
                StrategyNames.IsOn
            });
        }
        public async Task GivenAMatchingFeature_WhenLoading_ThenWeGetAArchivedFeature()
        {
            var createdNotMatching = new FeatureCreatedEvent {
                Name = "🤚",
                Path = "🌲/",
            };

            var created = new FeatureCreatedEvent {
                Name = "🦝",
                Path = "🌲/",
            };

            var archived = new FeatureArchivedEvent {
                Name = "🦝",
                Path = "🌲/",
            };

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(new List <IEvent> {
                created, createdNotMatching, archived
            });

            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            var aggregate = await this
                            .GivenAggregate(reader.Object, client.Object)
                            .WithLoad()();

            var features = aggregate.Features.ToList();

            features.Select(_ => _.Name).Should()
            .BeEquivalentTo(new List <string> {
                created.Name, createdNotMatching.Name
            });
            features.Where(_ => _.Name == archived.Name).Select(_ => _.State)
            .Should()
            .BeEquivalentTo(new List <FeatureState> {
                FeatureState.Archived
            });
            features.Where(_ => _.Name != archived.Name).Select(_ => _.State)
            .Should()
            .BeEquivalentTo(new List <FeatureState> {
                FeatureState.Draft
            });
        }
Пример #13
0
        public async Task GivenUnsupportedEventInStream_WhenReading_ThenWeReturnEmptyList()
        {
            var eventOne = new FeatureCreatedEvent
            {
                Name = "🦄",
            };

            var results = new Dictionary <string, byte[]>
            {
                { eventOne.Type, JsonSerializer.SerializeToUtf8Bytes(eventOne) },
            };

            var client = this.GivenIEventStoreClient()
                         .WithReadStreamAsync(this._stream, results);

            await PathStreamEventsReaderTestsExtenstions.ThenWeReturnEmptyList(this
                                                                               .GivenPathStreamEventsReader(client.Object)
                                                                               .WhenReading());
        }
Пример #14
0
        private void Apply(FeatureCreatedEvent e)
        {
            var pathAndName = PathHelper.CombineNameAndPath(e.Path, e.Name);
            var allExistingPathsAndNames = this.Features.Select(f => PathHelper.CombineNameAndPath(f.Path, f.Name));

            if (allExistingPathsAndNames.Contains(pathAndName))
            {
                throw new FeatureAlreadyExistsException();
            }

            this.Features = this.Features.Append(new Feature {
                Name       = e.Name,
                CreatedBy  = e.CreatedBy,
                CreatedOn  = e.CreatedOn,
                UpdatedOn  = e.CreatedOn,
                Path       = e.Path,
                State      = FeatureState.Draft,
                Strategies = Enumerable.Empty <IFeatureStrategy>()
            }).ToList();
        }
Пример #15
0
        public static async Task ThenWePublish(
            this Func <Task> funk,
            Mock <IEventStoreClient> mockedClient,
            FeatureCreatedEvent e)
        {
            await funk();

            mockedClient.Verify(
                _ => _.AppendToStreamAsync(
                    It.IsAny <FeatureStream>(),
                    It.IsAny <StreamState>(),
                    It.Is <IEnumerable <EventData> >(items =>
                                                     items.All(ed =>
                                                               ed.Type.Equals(EventTypes.FeatureCreated) &&
                                                               JsonSerializer.Deserialize <FeatureCreatedEvent>(ed.Data.ToArray(), null) !.Name.Equals(e.Name, StringComparison.InvariantCultureIgnoreCase)
                                                               )),
                    It.IsAny <Action <EventStoreClientOperationOptions>?>(),
                    It.IsAny <UserCredentials?>(),
                    It.IsAny <CancellationToken>()),
                Times.Once());
        }
        public async Task GivenEventsInStream_WhenReading_ThenWeReturnEventList()
        {
            var eventOne = new FeatureCreatedEvent
            {
                Name = "🦄",
            };

            var results = new Dictionary <string, byte[]>
            {
                { eventOne.Type, JsonSerializer.SerializeToUtf8Bytes(eventOne) },
            };

            var client = this.GivenIEventStoreClient()
                         .WithReadStreamAsync(this._stream, results);

            await this
            .GivenFeatureStreamEventsReader(client.Object)
            .WhenReading()
            .ThenWeReturnEventList(new List <IEvent> {
                eventOne
            });
        }
Пример #17
0
        public async Task GivenAConflictingFeature_WhenPublishingFeatureCreatedEvent_ThenWeThrowAConflictException()
        {
            var createdAlready = new FeatureCreatedEvent {
                Name = "bob",
                Path = "let/me/show/you",
            };

            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(new List <IEvent> {
                createdAlready
            });

            var aggregate = await this
                            .GivenAggregate(reader.Object, client.Object)
                            .WithLoad()();

            await aggregate
            .WhenPublishing(createdAlready)
            .ThenExceptionIsThrown <FeatureAlreadyExistsException>();
        }
Пример #18
0
        public async Task GivenCreatedFeature_WhenLoading_ThenIGetFeature()
        {
            var created = new FeatureCreatedEvent {
                Name = "bob",
                Path = "let/me/show/you",
            };

            var reader = this.GivenIReadStreamedEvents <FeatureStream>()
                         .WithEvents(new List <IEvent> {
                created
            });

            var client = this.GivenIEventStoreClient()
                         .WithAppendToStreamAsync(this._featureStream);

            var aggregate = await this
                            .GivenAggregate(reader.Object, client.Object)
                            .WithLoad()();

            aggregate.Features.Select(_ => _.Name).Should()
            .BeEquivalentTo(new List <string> {
                created.Name
            });
        }