public void OnCreateUser_Should_Emit_UserCreatedEvent()
        {
            Given(aggregate => { });

            var fullname = Fullname.Create(Faker.Name.FirstName(), Faker.Name.LastName());
            var email    = Email.Create($"{Faker.Random.Word()}@example.com");
            var password = Password.Create(Faker.Random.Word());

            var start = DateTimeUtc.Now();

            When(aggregate =>
            {
                aggregate.Create(
                    fullname,
                    email,
                    password);
            });
            var end = DateTimeUtc.Now();

            Then(aggregate =>
            {
                aggregate.Fullname.Should().Be(fullname);
                aggregate.Email.Should().Be(email);
                aggregate.Password.Should().Be(password);
            });

            Then <UserCreatedEvent>((aggregate, @event) =>
            {
                @event.Firstname.Should().Be(fullname.Firstname);
                @event.Lastname.Should().Be(fullname.Lastname);
                @event.Email.Should().Be(email.ToString());
                @event.Password.Should().Be(password.ToString());
                @event.CreatedOn.Should().NotBe(default);
        public async Task OnUpdatePassword_Should_Update_ReadModel()
        {
            var userId   = UserId.Create();
            var fullname = Fullname.Create(Faker.Name.FirstName(), Faker.Name.LastName());
            var email    = Email.Create($"{Faker.Random.Word()}@example.com");
            var password = Password.Create("secret");


            await GivenAsync(async repository =>
            {
                var aggregate = new User(userId);
                aggregate.Create(fullname, email, password);
                await repository.Save(aggregate, CancellationToken.None);
            });

            var updatedPassword = Password.Create(Faker.Random.Word());

            await When(async repository =>
            {
                var savedUser = await repository.Get(userId, CancellationToken.None);
                savedUser.UpdatePassword(updatedPassword);
                await repository.Save(savedUser, CancellationToken.None);
            });

            await Then <IDocumentRepository <UserModel> >(async (mediator, repository) =>
            {
                var user = await repository.SingleOrDefault(u => u.Id == userId.Id.ToString());
                user.Should().NotBeNull();
                user.Password.Should().Be(updatedPassword.ToString());
            });
        }
        public async Task OnCreate_Should_Write_And_Deserialize_Data()
        {
            var userId   = UserId.Create();
            var fullname = Fullname.Create(Faker.Name.FirstName(), Faker.Name.LastName());
            var email    = Email.Create($"{Faker.Random.Word()}@example.com");
            var password = Password.Create("secret");

            await GivenAsync(async repository =>
            {
                var aggregate = new User(userId);
                aggregate.Create(fullname, email, password);

                await repository.Save(aggregate, CancellationToken.None);
            });

            var result = await When(async repository => await repository.Get(userId, CancellationToken.None));

            Then(repository =>
            {
                result.Should().NotBeNull();
                result.Id.Should().Be(userId);
                result.Fullname.Should().Be(fullname);
                result.Email.Should().Be(email);
                result.Password.Should().Be(password);
            });
        }
        public async Task <Guid> Handle(CreateUserCommand request, CancellationToken cancellationToken)
        {
            var user = new User(UserId.Create());

            user.Create(
                Fullname.Create(request.Firstname, request.Lastname),
                Email.Create(request.Email),
                Password.Create(request.PlainPassword));

            await _userRepository.Save(user, cancellationToken);

            return(user.Id.Id);
        }
        public async Task Should_PassCorrectDetails_When_Calling_Save()
        {
            IReadOnlyCollection <IDomainEvent> eventsReceived = null;
            var streamNameReceived = string.Empty;

            Given(repository =>
            {
                _eventsRepoMock.Setup(r => r.Save(
                                          It.IsAny <IReadOnlyCollection <IDomainEvent> >(),
                                          It.IsAny <string>(),
                                          It.IsAny <CancellationToken>()))
                .Callback <IReadOnlyCollection <IDomainEvent>, string, CancellationToken>((
                                                                                              events,
                                                                                              streamName,
                                                                                              cancellationToken) =>
                {
                    eventsReceived     = events;
                    streamNameReceived = streamName;
                });
            });

            var aggregate = new User(UserId.Create("dev"));
            var fullname  = Fullname.Create("Mark", "Libres");
            var email     = Email.Create("*****@*****.**");
            var password  = Password.Create("secret");


            await WhenAsync(async repository =>
            {
                aggregate.Create(fullname, email, password);
                await repository.Save(aggregate, CancellationToken.None);
                return(Task.CompletedTask);
            });

            Then(repository =>
            {
                eventsReceived.Should()
                .NotBeNull()
                .And
                .HaveCount(1);
                streamNameReceived.Should().Be(aggregate.Id.StreamName);
                aggregate.UncommittedEvents.Should()
                .NotBeNullOrEmpty()
                .And
                .HaveCount(1);
                aggregate.CommittedEvents.Should()
                .BeNullOrEmpty();
            });
        }
        public Person CreatePerson()
        {
            var fullName        = Fullname.Create("Billy", "The", "Goat");
            var idNo            = RSAIdentityNumber.Create("21021112341134");
            var cellNo          = CellphoneNumber.Create("27743389201");
            var emailAddress    = EmailAddress.Create("*****@*****.**");
            var physicalAddress = new Address("4", "Table Mountain", "Cape Town", "7441", "Western Cape", "South Africa");
            var postalAddress   = new Address("4", "Table Mountain", "Cape Town", "7441", "Western Cape", "South Africa");
            var workAddress     = new Address("4", "Table Mountain", "Cape Town", "7441", "Western Cape", "South Africa");
            var money           = new Money(900000, "Coins", "ZAR");

            var person = new Person(fullName, idNo, cellNo, emailAddress, physicalAddress, postalAddress, workAddress, money, false, "Some Stuff About Me", MaritalStatus.Married, Gender.Goat, DateTime.Today);

            return(person);
        }
        public async Task Should_ReplayEvents_When_Loading_From_EventStore()
        {
            var userId           = UserId.Create("dev");
            var fullname         = Fullname.Create("Mark", "Libres");
            var email            = Email.Create("*****@*****.**");
            var passwordString   = "secret";
            var password         = Password.Create(passwordString);
            var userCreatedEvent = new UserCreatedEvent(userId, fullname.Firstname, fullname.Lastname, email.ToString(),
                                                        password.ToString());

            Given(repository =>
            {
                _eventsRepoMock.Setup(r => r.Get(
                                          It.IsAny <string>(),
                                          It.IsAny <CancellationToken>()))
                .ReturnsAsync((string streamName, CancellationToken cancellationToken) =>
                {
                    var result = new List <IDomainEvent> {
                        userCreatedEvent
                    }.AsReadOnly();
                    return(result);
                });
            });

            var aggregate = await WhenAsync(async repository => await repository.Get(userId, CancellationToken.None));

            Then(repository =>
            {
                aggregate.Should().NotBeNull();
                aggregate.Fullname.Should().Be(fullname);
                aggregate.Email.Should().Be(email);
                aggregate.Password.Should().Be(password);
                aggregate.CommittedEvents.Should()
                .NotBeNullOrEmpty()
                .And
                .HaveCount(1)
                .And
                .ContainEquivalentOf(userCreatedEvent);
                aggregate.UncommittedEvents.Should()
                .BeNullOrEmpty();
            });
        }
 protected void Handle(UserCreatedEvent @event)
 {
     Fullname = Fullname.Create(@event.Firstname, @event.Lastname);
     Email    = Email.Create(@event.Email);
     Password = Password.Create(@event.Password, false);
 }