public async Task Valid_command_succeeds()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(ConfigureServices);

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName   = "Andrzej",
                    LastName    = "Strzelba",
                    Email       = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber = Consts.FakePhoneNumber,
                    AboutMe     = "ala ma kota",
                    Region      = "Wolne Miasto Gdańsk",
                    PreferredLecturingCities = new[] { "Wadowice" },
                    PreferredTrainingIds     = new[] { 1 },
                    GdprConsentGiven         = true
                };

                var result = await engine.Execute(command);

                Assert.True(result.IsSuccess);
            }
        }
示例#2
0
        public async Task <Result <Nothing, Error> > Handle(SubmitRecruitmentForm.Command request, CancellationToken cancellationToken)
        {
            var options            = _options.Value;
            var preferredTrainings = await _repo.GetByIds(request.PreferredTrainingIds);

            var enrollment   = _enrollmentRepo.Query().Where(x => x.Email == request.Email).FirstOrDefault();
            var enrollmentId = enrollment != null ? enrollment.Id : EnrollmentId.New;

            var result = await _aggregateStore.Update <EnrollmentAggregate, EnrollmentId, Result <Nothing, Error> >(
                enrollmentId, SourceId.New,
                (aggregate) => aggregate.SubmitRecruitmentForm(request, preferredTrainings, _clock.GetCurrentInstant()),
                cancellationToken);

            return(await result.Unwrap()
                   .Tap(async _ =>
            {
                await _aggregateStore.UpdateAsync <EnrollmentAggregate, EnrollmentId>(
                    enrollmentId, SourceId.New,
                    async(aggregate, token) =>
                {
                    var body = await BuildMessageBody(options.GreetingEmail, aggregate);
                    var message = _emailService.CreateMessage(request.Email, options.GreetingEmail.Subject, body, isBodyHtml: options.GreetingEmail.IsBodyHtml);
                    await _emailService.Send(message, cancellationToken)
                    .Tap(() => aggregate.RecordEmailSent(_clock.GetCurrentInstant(), message))
                    .OnFailure(() => aggregate.RecordEmailSendingFailed(_clock.GetCurrentInstant(), message));
                }, cancellationToken);
            }));
        }
        public async Task Valid_command_emits_single_EmailSent_event_when_EmailService_sends_email()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(ConfigureServices);

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName   = "Andrzej",
                    LastName    = "Strzelba",
                    Email       = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber = Consts.FakePhoneNumber,
                    AboutMe     = "ala ma kota",
                    Region      = "Wolne Miasto Gdańsk",
                    PreferredLecturingCities = new[] { "Wadowice" },
                    PreferredTrainingIds     = new[] { 1 },
                    GdprConsentGiven         = true
                };

                var result = await engine.Execute(command);

                Assert.True(result.IsSuccess);
                var eventStore = scope.ServiceProvider.GetRequiredService <EventFlow.EventStores.IEventStore>();
                var events     = await eventStore.LoadAllEventsAsync(EventFlow.EventStores.GlobalPosition.Start, 2, System.Threading.CancellationToken.None);

                var domainEvent = Assert.Single(events.DomainEvents, ev => ev.EventType == typeof(EmailSent));
                var ev          = Assert.IsType <EmailSent>(domainEvent.GetAggregateEvent());
                Assert.Equal(SubmitRecruitmentFormHandler.MessageTitle, ev.Subject);
            }
        }
        public async Task Command_must_be_issued_during_campaign()
        {
            var clock = new NodaTime.Testing.FakeClock(NodaTime.Instant.FromDateTimeUtc(DateTime.UtcNow).Plus(NodaTime.Duration.FromDays(30)));

            var sp = new ServiceProviderBuilder().BuildServiceProvider(services => {
                ConfigureServices(services);
                services.Remove <NodaTime.IClock>();
                services.AddSingleton <NodaTime.IClock>(clock);
            });

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName                = "Andrzej",
                    LastName                 = "Strzelba",
                    Email                    = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber              = Consts.FakePhoneNumber,
                    AboutMe                  = "ala ma kota",
                    Region                   = "Wolne Miasto Gdańsk",
                    PreferredTrainingIds     = new[] { 1 },
                    PreferredLecturingCities = new[] { "Wolne Miasto Gdańsk" },
                    GdprConsentGiven         = true
                };

                var result = await engine.Execute(command);

                Assert.True(result.IsFailure);
                var error = Assert.IsType <Domain.Error.DomainError>(result.Error);
                Assert.Equal(SubmitRecruitmentForm_ErrorMessages.SubmissionMustOccurDuringCampaign, error.Message);
            }
        }
        public async Task Command_cannot_specify_duplicate_preferred_cities()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(ConfigureServices);

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName   = "Andrzej",
                    LastName    = "Strzelba",
                    Email       = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber = Consts.FakePhoneNumber,
                    AboutMe     = "ala ma kota",
                    Region      = "Wolne Miasto Gdańsk",
                    PreferredLecturingCities = new[] { "Wolne Miasto Gdańsk", "Wolne Miasto Gdańsk" },
                    PreferredTrainingIds     = new[] { 1, 2, 3, 5, 8, 13 },
                    GdprConsentGiven         = true
                };

                var result = await engine.Execute(command);

                Assert.True(result.IsFailure);
                var error   = Assert.IsType <Domain.Error.ValidationFailed>(result.Error);
                var failure = Assert.Single(error.Failures);
                Assert.Equal(nameof(command.PreferredLecturingCities), failure.PropertyName);
                Assert.Single(failure.Errors);
                Assert.Equal(SubmitRecruitmentForm_ErrorMessages.PreferredLecturingCities_cannot_have_duplicates, failure.Errors.Single());
            }
        }
        public async Task All_specified_trainings_must_exist()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(ConfigureServices);

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName   = "Andrzej",
                    LastName    = "Strzelba",
                    Email       = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber = Consts.FakePhoneNumber,
                    AboutMe     = "ala ma kota",
                    Region      = "Wolne Miasto Gdańsk",
                    PreferredLecturingCities = new[] { "Wolne Miasto Gdańsk" },
                    PreferredTrainingIds     = new[] { 1, 21, 37 },
                    GdprConsentGiven         = true
                };

                var result = await engine.Execute(command);

                Assert.True(result.IsFailure);
                var error = Assert.IsType <Error.ResourceNotFound>(result.Error);
                Assert.Equal(SubmitRecruitmentForm_ErrorMessages.SomeTrainingsWereNotFound, error.Message);
            }
        }
        public async Task All_tranings_in_command_must_belong_to_the_same_campaign()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(ConfigureServices);

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName   = "Andrzej",
                    LastName    = "Strzelba",
                    Email       = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber = Consts.FakePhoneNumber,
                    AboutMe     = "ala ma kota",
                    Region      = "Wolne Miasto Gdańsk",
                    PreferredLecturingCities = new[] { "Wolne Miasto Gdańsk" },
                    PreferredTrainingIds     = new[] { 1, 2 },
                    GdprConsentGiven         = true
                };

                var result = await engine.Execute(command);

                Assert.True(result.IsFailure);
                var error = Assert.IsType <Domain.Error.DomainError>(result.Error);
                Assert.Equal(SubmitRecruitmentForm_ErrorMessages.PreferredTrainingsMustBelongToTheSameCampaign, error.Message);
            }
        }
        public async Task Command_must_specify_at_least_one_training()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(ConfigureServices);

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName   = "Andrzej",
                    LastName    = "Strzelba",
                    Email       = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber = Consts.FakePhoneNumber,
                    AboutMe     = "ala ma kota",
                    Region      = "Wolne Miasto Gdańsk",
                    PreferredLecturingCities = new[] { "Wolne Miasto Gdańsk" },
                    PreferredTrainingIds     = Array.Empty <int>(),
                    GdprConsentGiven         = true
                };

                var result = await engine.Execute(command);

                Assert.True(result.IsFailure);
                var error = Assert.IsType <Error.ValidationFailed>(result.Error);
                AssertHelpers.SingleError(nameof(command.PreferredTrainingIds), SubmitRecruitmentForm_ErrorMessages.PreferredTrainingsMustBeSpecified, error.Failures);
            }
        }
        public async Task Command_MustContain_SubmissionDate_FirstName_LastName_EmailAddress_PhoneNumber_AboutMe()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(ConfigureServices);

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    PreferredTrainingIds = new[] { 1 }, GdprConsentGiven = true
                };

                var result = await engine.Execute(command);

                Assert.True(result.IsFailure);
                var error = Assert.IsType <Error.ValidationFailed>(result.Error);
                Assert.Collection(error.Failures,
                                  error => AssertHelpers.SingleError(nameof(command.FirstName), SubmitRecruitmentForm_ErrorMessages.FirstNameIsRequired, error),
                                  error => AssertHelpers.SingleError(nameof(command.LastName), SubmitRecruitmentForm_ErrorMessages.LastNameIsRequired, error),
                                  error => AssertHelpers.SingleError(nameof(command.Email), SubmitRecruitmentForm_ErrorMessages.EmailIsRequired, error),
                                  error => AssertHelpers.SingleError(nameof(command.PhoneNumber), SubmitRecruitmentForm_ErrorMessages.PhoneNumberIsRequired, error),
                                  error => AssertHelpers.SingleError(nameof(command.AboutMe), SubmitRecruitmentForm_ErrorMessages.AboutMeIsRequired, error),
                                  error => AssertHelpers.SingleError(nameof(command.Region), SubmitRecruitmentForm_ErrorMessages.RegionIsRequired, error),
                                  error => AssertHelpers.SingleError(nameof(command.PreferredLecturingCities), SubmitRecruitmentForm_ErrorMessages.PreferredLecturingCities_must_be_specified, error)
                                  );
            }
        }
        public void After_executing_command__aggregate_contains_name_email_phone_region_cities_trainings_and_campaign()
        {
            // Arrange
            var now     = NodaTime.SystemClock.Instance.GetOffsetDateTime();
            var command = new SubmitRecruitmentForm.Command()
            {
                FirstName   = "Andrzej",
                LastName    = "Strzelba",
                Email       = EmailAddress.Parse("*****@*****.**"),
                PhoneNumber = Consts.FakePhoneNumber,
                AboutMe     = "ala ma kota",
                Region      = "małopolskie",
                PreferredLecturingCities = new[] { "Wadowice" },
                PreferredTrainingIds     = new[] { 1 },
                GdprConsentGiven         = true
            };
            var enrollment = new EnrollmentAggregate(EnrollmentAggregate.EnrollmentId.New);
            var campaign   = new Campaign(
                startDateTime: now.Minus(Duration.FromDays(3)),
                endDateTime: now.Plus(Duration.FromDays(3)),
                editionId: 1, name: "kampania testowa");

            campaign.GetType().GetProperty(nameof(campaign.Id)).SetValue(campaign, 1);
            var training = new Training(
                address: "Papieska 21/37",
                city: "Wadowice",
                startDateTime: now.Plus(Duration.FromDays(7)),
                endDateTime: now.Plus(Duration.FromDays(7) + Duration.FromHours(4)),
                coordinatorId: Guid.NewGuid());

            training.GetType().GetProperty(nameof(training.ID)).SetValue(training, 1);
            campaign.ScheduleTraining(training);
            var trainings = new[] { training };

            // Act
            var result = enrollment.SubmitRecruitmentForm(command, trainings, now.ToInstant());

            // Assert
            result.IsSuccess.Should().BeTrue();
            enrollment.FirstName.Should().Be("Andrzej");
            enrollment.LastName.Should().Be("Strzelba");
            enrollment.FullName.Should().Be("Andrzej Strzelba");
            enrollment.Email.ToString().Should().Be("*****@*****.**");
            enrollment.PhoneNumber.Should().Be(Consts.FakePhoneNumber);

            enrollment.Region.Should().Be("małopolskie");
            enrollment.PreferredLecturingCities.Should().BeEquivalentTo(new[] { "Wadowice" });
            enrollment.PreferredTrainingIds.Should().BeEquivalentTo(new[] { 1 });
            enrollment.CampaignId.Should().Be(1);
        }
 public static RecruitmentFormSubmitted From(SubmitRecruitmentForm.Command command, Instant submissionDate, int campaignID)
 {
     return(new RecruitmentFormSubmitted(
                submissionDate,
                command.FirstName,
                command.LastName,
                command.Email,
                command.PhoneNumber,
                command.AboutMe,
                campaignID,
                command.Region,
                command.PreferredLecturingCities,
                command.PreferredTrainingIds,
                command.GdprConsentGiven));
 }
        public async Task After_executing_command_enrollments_contain_that_submission()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(ConfigureServices);

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName   = "Andrzej",
                    LastName    = "Strzelba",
                    Email       = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber = Consts.FakePhoneNumber,
                    AboutMe     = "ala ma kota",
                    Region      = "Wolne Miasto Gdańsk",
                    PreferredLecturingCities = new[] { "Wadowice" },
                    PreferredTrainingIds     = new[] { 1 },
                    GdprConsentGiven         = true
                };

                var result = await engine.Execute(command);

                Assert.True(result.IsSuccess);
            }

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var results = await engine.Query(new GetSubmissions.Query());

                var readModel = Assert.Single(results);
                var id        = EnrollmentAggregate.EnrollmentId.With(readModel.Id);
                Assert.Equal("Andrzej", readModel.FirstName);
                Assert.Equal("Strzelba", readModel.LastName);
                Assert.Equal(EmailAddress.Parse("*****@*****.**"), readModel.Email);
                Assert.Equal(Consts.FakePhoneNumber, readModel.PhoneNumber);
                Assert.Equal("ala ma kota", readModel.AboutMe);
                Assert.Equal(1, readModel.Campaign.ID);
                Assert.Equal("Wolne Miasto Gdańsk", readModel.Region);
                var preferredTraining = Assert.Single(readModel.PreferredTrainings);
                Assert.Equal(1, preferredTraining.ID);
                Assert.Single(readModel.PreferredLecturingCities, "Wadowice");
            }
        }
        public async Task Valid_command_emits_single_EmailSendingFailed_event_when_EmailService_fails_to_send_email()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(services =>
            {
                ConfigureServices(services);

                var failingEmailMock = new Mock <IEmailService>();
                failingEmailMock
                .Setup(x => x.CreateMessage(It.IsAny <EmailAddress>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <IEnumerable <EmailAttachment> >()))
                .Returns((EmailAddress email, string subject, string body, bool isHtml, IEnumerable <EmailAttachment> attachments) => new SucceedingEmailService().CreateMessage(email, subject, body, isHtml, attachments));
                failingEmailMock.Setup(x => x.Send(It.IsAny <EmailMessage>(), CancellationToken.None)).Returns(Task.FromResult(Result.Failure("error")));

                services.Remove <IEmailService>();
                services.AddSingleton(failingEmailMock.Object);
            });

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName   = "Andrzej",
                    LastName    = "Strzelba",
                    Email       = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber = Consts.FakePhoneNumber,
                    AboutMe     = "ala ma kota",
                    Region      = "woj. małopolskie",
                    PreferredLecturingCities = new[] { "Wadowice" },
                    PreferredTrainingIds     = new[] { 1 },
                    GdprConsentGiven         = true
                };

                var result = await engine.Execute(command);

                Assert.True(result.IsSuccess);
                var eventStore = scope.ServiceProvider.GetRequiredService <EventFlow.EventStores.IEventStore>();
                var events     = await eventStore.LoadAllEventsAsync(EventFlow.EventStores.GlobalPosition.Start, 2, CancellationToken.None);

                var domainEvent = Assert.Single(events.DomainEvents, ev => ev.EventType == typeof(EmailSendingFailed));
                var ev          = Assert.IsType <EmailSendingFailed>(domainEvent.GetAggregateEvent());
                Assert.Equal(SubmitRecruitmentFormHandler.MessageTitle, ev.Subject);
            }
        }
        public async Task Querying_for_existing_enrollment_returns_that_enrollment_events()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(ConfigureServices);

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName   = "Andrzej",
                    LastName    = "Strzelba",
                    Email       = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber = Consts.FakePhoneNumber,
                    AboutMe     = "ala ma kota",
                    Region      = "Wolne Miasto Gdańsk",
                    PreferredLecturingCities = new[] { "Wadowice" },
                    PreferredTrainingIds     = new[] { 1 },
                    GdprConsentGiven         = true
                };
                var result = await engine.Execute(command);

                Assert.True(result.IsSuccess);
            }

            using (var scope = sp.CreateScope())
            {
                var engine      = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var enrollments = await engine.Query(new GetSubmissions.Query());

                var result = await engine.Query(new GetEnrollmentDetails.QueryByEnrollmentId()
                {
                    EnrollmentID = enrollments.Single().Id
                });

                Assert.True(result.IsSuccess);
                var enrollment = result.Value;
                Assert.Contains(enrollment.Events, evt => evt.GetType() == typeof(GetEnrollmentDetails.RecruitmentFormSubmittedEventData));
            }
        }
        public async Task Valid_command_emits_single_RecruitmentFormSubmitted_event()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(ConfigureServices);

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName   = "Andrzej",
                    LastName    = "Strzelba",
                    Email       = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber = Consts.FakePhoneNumber,
                    AboutMe     = "ala ma kota",
                    Region      = "małopolskie",
                    PreferredLecturingCities = new[] { "Wadowice" },
                    PreferredTrainingIds     = new[] { 1 },
                    GdprConsentGiven         = true
                };

                var result = await engine.Execute(command);

                Assert.True(result.IsSuccess);
                var eventStore = scope.ServiceProvider.GetRequiredService <EventFlow.EventStores.IEventStore>();
                var events     = await eventStore.LoadAllEventsAsync(EventFlow.EventStores.GlobalPosition.Start, 2, System.Threading.CancellationToken.None);

                var domainEvent = Assert.Single(events.DomainEvents, ev => ev.EventType == typeof(RecruitmentFormSubmitted));
                var e           = Assert.IsType <RecruitmentFormSubmitted>(domainEvent.GetAggregateEvent());
                Assert.Equal("Andrzej", e.FirstName);
                Assert.Equal("Strzelba", e.LastName);
                Assert.Equal("*****@*****.**", e.Email.ToString());
                Assert.Equal(Consts.FakePhoneNumber, e.PhoneNumber);
                Assert.Equal("ala ma kota", e.AboutMe);
                Assert.Equal("małopolskie", e.Region);
                Assert.Single(e.PreferredLecturingCities, "Wadowice");
                Assert.Single(e.PreferredTrainingIds, 1);
                Assert.True(e.GdprConsentGiven);
            }
        }
示例#16
0
        public Result <Nothing, Error> SubmitRecruitmentForm(SubmitRecruitmentForm.Command command, IReadOnlyCollection <Training> preferredTrainings, Instant now)
        {
            Guard.Against.Null(command, nameof(command));
            Guard.Against.Null(preferredTrainings, nameof(preferredTrainings));
            Guard.Against.Default(now, nameof(now));

            return
                (Validate(new SubmitRecruitmentForm.Validator(), command)
                 .Ensure(
                     _ => preferredTrainings.Select(x => x.ID).OrderBy(x => x).SequenceEqual(command.PreferredTrainingIds.OrderBy(x => x)),
                     new Error.ResourceNotFound(SubmitRecruitmentForm_ErrorMessages.SomeTrainingsWereNotFound))
                 .Ensure(
                     _ => preferredTrainings.Select(x => x.Campaign).Distinct().Count() == 1,
                     new Error.DomainError(SubmitRecruitmentForm_ErrorMessages.PreferredTrainingsMustBelongToTheSameCampaign))
                 .Ensure(
                     _ => preferredTrainings.First().Campaign.Interval.Contains(now),
                     new Error.DomainError(SubmitRecruitmentForm_ErrorMessages.SubmissionMustOccurDuringCampaign))
                 .Ensure(
                     _ => preferredTrainings.All(x => x.StartDateTime.ToInstant() > now),
                     new Error.DomainError(SubmitRecruitmentForm_ErrorMessages.PreferredTrainingsMustOccurInTheFuture))
                 .Tap(() => Emit(RecruitmentFormSubmitted.From(command, now, preferredTrainings.First().Campaign.Id))));
        }
        public async Task <IActionResult> Create(SubmitRecruitmentForm.Command command)
        {
            var result = await _engine.Execute(command);

            return(result.MatchToActionResult(success => Ok()));
        }
        public async Task Querying_for_existing_enrollment_returns_that_enrollment_summary()
        {
            var sp = new ServiceProviderBuilder().BuildServiceProvider(ConfigureServices);

            using (var scope = sp.CreateScope())
            {
                var engine  = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var command = new SubmitRecruitmentForm.Command()
                {
                    FirstName   = "Andrzej",
                    LastName    = "Strzelba",
                    Email       = EmailAddress.Parse("*****@*****.**"),
                    PhoneNumber = Consts.FakePhoneNumber,
                    AboutMe     = "ala ma kota",
                    Region      = "Wolne Miasto Gdańsk",
                    PreferredLecturingCities = new[] { "Wadowice" },
                    PreferredTrainingIds     = new[] { 1, 2 },
                    GdprConsentGiven         = true
                };
                var result = await engine.Execute(command);

                Assert.True(result.IsSuccess);
            }

            using (var scope = sp.CreateScope())
            {
                var engine      = scope.ServiceProvider.GetRequiredService <ISzlemEngine>();
                var enrollments = await engine.Query(new GetSubmissions.Query());

                var result = await engine.Query(new GetEnrollmentDetails.QueryByEnrollmentId()
                {
                    EnrollmentID = enrollments.Single().Id
                });

                Assert.True(result.IsSuccess);
                var enrollment = result.Value;
                Assert.Equal(enrollments.Single().Id, enrollment.ID);
                Assert.Equal("Andrzej", enrollment.FirstName);
                Assert.Equal("Strzelba", enrollment.LastName);
                Assert.Equal(EmailAddress.Parse("*****@*****.**"), enrollment.Email);
                Assert.Equal(Consts.FakePhoneNumber, enrollment.PhoneNumber);
                Assert.Single(enrollment.PreferredLecturingCities, "Wadowice");

                Assert.Collection(enrollment.PreferredTrainings,
                                  first => {
                    Assert.Equal(1, first.ID);
                    Assert.Equal(trainerID, first.CoordinatorID);
                    Assert.Equal("Jan Paweł II", first.CoordinatorName);
                    Assert.Equal("Wadowice", first.City);
                },
                                  second => {
                    Assert.Equal(2, second.ID);
                    Assert.Equal(trainerID, second.CoordinatorID);
                    Assert.Equal("Jan Paweł II", second.CoordinatorName);
                    Assert.Equal("Wadowice", second.City);
                });

                enrollment.IsCurrentSubmission.Should().BeTrue();
                enrollment.IsOldSubmission.Should().BeFalse();
                enrollment.CanRecordTrainingResults.Should().BeFalse();
            }
        }