public async Task If_candidate_resigned_permanently__AvailableCandidates_do_not_contain_that_candidate()
        {
            // Arrange
            var trainerId = Guid.NewGuid();

            (var campaignRepo, var trainingRepo, var trainerProvider) = BuildMocks(trainerId, 1, 1);
            var enrollmentId     = EnrollmentAggregate.EnrollmentId.New;
            var enrollmentRepo   = new EnrollmentRepository();
            var readStoreManager = new ReadStoreManager(enrollmentRepo, campaignRepo, trainingRepo);

            var events = new IDomainEvent[]
            {
                new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>(
                    new RecruitmentFormSubmitted(clock.GetCurrentInstant().Minus(anHour), "Andrzej", "Strzelba", EmailAddress.Parse("*****@*****.**"), Consts.FakePhoneNumber, "jo", 1, "Wolne Miasto Gdańsk", new[] { "Gdańsk", "Wrzeszcz", "Oliwa" }, new[] { 1 }, true),
                    new Metadata(), clock.GetCurrentInstant().ToDateTimeOffset(), enrollmentId, 1),
                new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateResignedPermanently>(
                    new CandidateResignedPermanently(trainerId, Recruitment.Enrollments.CommunicationChannel.IncomingApiRequest, string.Empty, string.Empty),
                    new Metadata(), clock.GetCurrentInstant().ToDateTimeOffset(), enrollmentId, 2)
            };
            await readStoreManager.UpdateReadStoresAsync(events, CancellationToken.None);

            // Act
            var handler = new DetailsHandler(clock, trainingRepo, trainerProvider, enrollmentRepo);
            var result  = await handler.Handle(new Details.Query()
            {
                TrainingId = 1
            }, CancellationToken.None);

            // Assert
            Assert.True(result.HasValue);
            Assert.Equal(TrainingTiming.Future, result.Value.Timing);
            var futureTraining = Assert.IsType <Details.FutureTrainingDetails>(result.Value);

            Assert.Empty(futureTraining.AvailableCandidates);
        }
        public async Task If_candidate_was_not_reported_as_present_or_absent__he_is_not_contained_in_PresentCandidates()
        {
            // Arrange
            var trainerId = Guid.NewGuid();

            (var campaignRepo, var trainingRepo, var trainerProvider) = BuildMocks(trainerId, 1, 1);
            var enrollmentId     = EnrollmentAggregate.EnrollmentId.New;
            var enrollmentRepo   = new EnrollmentRepository();
            var readStoreManager = new ReadStoreManager(enrollmentRepo, campaignRepo, trainingRepo);

            var events = new IDomainEvent[]
            {
                new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>(
                    new RecruitmentFormSubmitted(clock.GetCurrentInstant().Minus(anHour), "Andrzej", "Strzelba", EmailAddress.Parse("*****@*****.**"), Consts.FakePhoneNumber, "jo", 1, "Wolne Miasto Gdańsk", new[] { "Gdańsk", "Wrzeszcz", "Oliwa" }, new[] { 1 }, true),
                    new Metadata(), clock.GetCurrentInstant().ToDateTimeOffset(), enrollmentId, 1),
                new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>(
                    new CandidateAcceptedTrainingInvitation(trainerId, Recruitment.Enrollments.CommunicationChannel.OutgoingPhone, 1, string.Empty),
                    new Metadata(), clock.GetCurrentInstant().ToDateTimeOffset(), enrollmentId, 2)
            };
            await readStoreManager.UpdateReadStoresAsync(events, CancellationToken.None);

            // Act
            var handler = new DetailsHandler(clock, trainingRepo, trainerProvider, enrollmentRepo);
            var result  = await handler.Handle(new Details.Query()
            {
                TrainingId = 1
            }, CancellationToken.None);

            // Assert
            Assert.True(result.HasValue);
            Assert.Equal(TrainingTiming.Past, result.Value.Timing);
            var pastTraining = Assert.IsType <Details.PastTrainingDetails>(result.Value);

            Assert.Empty(pastTraining.PresentCandidates);
        }
        public async Task If_candidate_prefers_training__PreferringCandidates_contain_that_candidate()
        {
            // Arrange
            var trainerId      = Guid.NewGuid();
            var sourceTraining = new Training("Papieska 21/37", "Wadowice", now.Plus(aWeek), now.Plus(aWeek + anHour), trainerId);

            sourceTraining.GetType().GetProperty(nameof(sourceTraining.ID)).SetValue(sourceTraining, 1);

            var trainingRepo = Mock.Of <ITrainingRepository>(
                repo => repo.GetById(1) == Task.FromResult(Maybe <Training> .From(sourceTraining)),
                MockBehavior.Strict);
            var trainerProvider = Mock.Of <ITrainerProvider>(
                provider => provider.GetTrainerDetails(trainerId) == Task.FromResult(Maybe <TrainerDetails> .From(
                                                                                         new TrainerDetails()
            {
                Guid = trainerId, Name = "Andrzej Strzelba"
            })),
                MockBehavior.Strict);

            var enrollment = new EnrollmentReadModel()
            {
                Id = EnrollmentAggregate.EnrollmentId.New,
                PreferredTrainings = new[] { new EnrollmentReadModel.TrainingSummary()
                                             {
                                                 ID = 1
                                             } }
            };
            var enrollmentRepo = Mock.Of <IEnrollmentRepository>(
                repo => repo.Query() == new[] { enrollment }.AsQueryable(),
                MockBehavior.Strict);

            var handler = new DetailsHandler(clock, trainingRepo, trainerProvider, enrollmentRepo);

            // Act
            var result = await handler.Handle(new Details.Query()
            {
                TrainingId = 1
            }, CancellationToken.None);

            // Assert
            Assert.True(result.HasValue);
            Assert.Equal(TrainingTiming.Future, result.Value.Timing);
            var futureTraining = Assert.IsType <Details.FutureTrainingDetails>(result.Value);
            var candidate      = Assert.Single(futureTraining.PreferringCandidates);

            Assert.Equal(enrollment.Id.GetGuid(), candidate.Id);
        }
        public async Task If_candidate_was_invited_to_training__AvailableCandidates_do_not_contain_that_candidate()
        {
            // Arrange
            var trainerId = Guid.NewGuid();

            (var campaignRepo, var trainingRepo, var trainerProvider) = BuildMocks(trainerId, 1, 1);

            var enrollment = new EnrollmentReadModel()
            {
                Id = EnrollmentAggregate.EnrollmentId.New,
                PreferredTrainings = new[] { new EnrollmentReadModel.TrainingSummary()
                                             {
                                                 ID = 1
                                             } },
                SelectedTraining = new EnrollmentReadModel.TrainingSummary()
                {
                    ID = 1
                }
            };
            var enrollmentRepo = Mock.Of <IEnrollmentRepository>(
                repo => repo.Query() == new[] { enrollment }.AsQueryable(),
                MockBehavior.Strict);

            var handler = new DetailsHandler(clock, trainingRepo, trainerProvider, enrollmentRepo);

            // Act
            var result = await handler.Handle(new Details.Query()
            {
                TrainingId = 1
            }, CancellationToken.None);

            // Assert
            Assert.True(result.HasValue);
            Assert.Equal(TrainingTiming.Future, result.Value.Timing);
            var futureTraining = Assert.IsType <Details.FutureTrainingDetails>(result.Value);

            Assert.Empty(futureTraining.AvailableCandidates);
        }