public void Training_invitation_acceptance_must_specify_one_of_preferred_trainings()
        {
            // Arrange
            var id     = EnrollmentAggregate.EnrollmentId.New;
            var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>(
                new RecruitmentFormSubmitted(
                    NodaTime.SystemClock.Instance.GetCurrentInstant(),
                    "Andrzej", "Strzelba",
                    EmailAddress.Parse("*****@*****.**"), Consts.FakePhoneNumber,
                    "ala ma kota", 1, "małopolskie", new[] { "Wadowice" }, new[] { 1 }, true),
                new Metadata(),
                DateTimeOffset.Now,
                id,
                1);
            var enrollment = new EnrollmentAggregate(id);

            enrollment.ApplyEvents(new[] { event1 });

            var training             = CreateTrainingInFutureWithId(1);
            var recordingCoordinator = new Models.Users.ApplicationUser()
            {
                Id = Guid.NewGuid()
            };
            var command = new RecordAcceptedTrainingInvitation.Command()
            {
                EnrollmentId         = id.GetGuid(),
                CommunicationChannel = CommunicationChannel.OutgoingEmail,
                AdditionalNotes      = "brak notatek"
            };

            // Act
            var result = enrollment.RecordCandidateAcceptedTrainingInvitation(command, recordingCoordinator, new[] { training }, NodaTime.SystemClock.Instance.GetCurrentInstant());

            // Assert
            Assert.False(result.IsSuccess);
            var error   = Assert.IsType <Error.ValidationFailed>(result.Error);
            var failure = Assert.Single(error.Failures);

            Assert.Equal(nameof(command.SelectedTrainingID), failure.PropertyName);
            Assert.Single(failure.Errors);
        }
        public void After_accepting_invitation_can_record_training_attendance()
        {
            // Arrange
            var id     = EnrollmentAggregate.EnrollmentId.New;
            var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>(
                new RecruitmentFormSubmitted(
                    NodaTime.SystemClock.Instance.GetCurrentInstant(),
                    "Andrzej", "Strzelba",
                    EmailAddress.Parse("*****@*****.**"), Consts.FakePhoneNumber,
                    "ala ma kota", 1, "małopolskie", new[] { "Wadowice" }, new[] { 1 }, true),
                new Metadata(), DateTimeOffset.Now, id, 1
                );
            var event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateRefusedTrainingInvitation>(
                new CandidateRefusedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, "kandydat nie ma czasu", string.Empty),
                new Metadata(), DateTimeOffset.Now, id, 2
                );
            var enrollment = new EnrollmentAggregate(id);

            enrollment.ApplyEvents(new IDomainEvent[] { event1, event2 });
            var recordingCoordinator = new Models.Users.ApplicationUser()
            {
                Id = Guid.NewGuid()
            };

            // Act
            var result = enrollment.RecordCandidateAcceptedTrainingInvitation(
                new RecordAcceptedTrainingInvitation.Command()
            {
                EnrollmentId         = enrollment.Id.GetGuid(),
                CommunicationChannel = CommunicationChannel.OutgoingPersonalContact,
                AdditionalNotes      = "brak notatek",
                SelectedTrainingID   = 1
            },
                recordingCoordinator,
                new[] { CreateTrainingInFutureWithId(1) },
                NodaTime.SystemClock.Instance.GetCurrentInstant());

            // Assert
            Assert.True(result.IsSuccess);
            Assert.False(enrollment.CanRecordTrainingResults(new[] { CreateTrainingInFutureWithId(1) }, NodaTime.SystemClock.Instance.GetCurrentInstant()).IsSuccess);
        }
        public void Cannot_accept_invitation_to_training_with_ID_not_present_in_available_trainings()
        {
            // Arrange
            var id     = EnrollmentAggregate.EnrollmentId.New;
            var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>(
                new RecruitmentFormSubmitted(
                    NodaTime.SystemClock.Instance.GetCurrentInstant(),
                    "Andrzej", "Strzelba",
                    EmailAddress.Parse("*****@*****.**"), Consts.FakePhoneNumber,
                    "ala ma kota", 1, "małopolskie", new[] { "Wadowice" }, new[] { 1 }, true),
                new Metadata(),
                DateTimeOffset.Now,
                id,
                1);
            var enrollment = new EnrollmentAggregate(id);

            enrollment.ApplyEvents(new[] { event1 });

            var training             = CreateTrainingInFutureWithId(1);
            var recordingCoordinator = new Models.Users.ApplicationUser()
            {
                Id = Guid.NewGuid()
            };
            var command = new RecordAcceptedTrainingInvitation.Command()
            {
                EnrollmentId         = id.GetGuid(),
                CommunicationChannel = CommunicationChannel.OutgoingEmail,
                SelectedTrainingID   = 2,
                AdditionalNotes      = "brak notatek"
            };

            // Act
            var result = enrollment.RecordCandidateAcceptedTrainingInvitation(command, recordingCoordinator, new[] { training }, NodaTime.SystemClock.Instance.GetCurrentInstant());

            // Assert
            Assert.False(result.IsSuccess);
            var error = Assert.IsType <Error.ResourceNotFound>(result.Error);

            Assert.Equal(RecordAcceptedTrainingInvitation_ErrorMessages.TrainingNotFound, error.Message);
        }
        public void Cannot_accept_training_invitation_after_training_start_datetime()
        {
            // Arrange
            var id     = EnrollmentAggregate.EnrollmentId.New;
            var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>(
                new RecruitmentFormSubmitted(
                    NodaTime.SystemClock.Instance.GetCurrentInstant(),
                    "Andrzej", "Strzelba",
                    EmailAddress.Parse("*****@*****.**"), Consts.FakePhoneNumber,
                    "ala ma kota", 1, "małopolskie", new[] { "Wadowice" }, new[] { 1 }, true),
                new Metadata(), DateTimeOffset.Now, id, 1
                );
            var enrollment = new EnrollmentAggregate(id);

            enrollment.ApplyEvents(new IDomainEvent[] { event1 });
            var recordingCoordinator = new Models.Users.ApplicationUser()
            {
                Id = Guid.NewGuid()
            };
            var training = CreateTrainingWithIdAndOffset(1, Duration.FromHours(-1));

            // Act
            var result = enrollment.RecordCandidateAcceptedTrainingInvitation(
                new RecordAcceptedTrainingInvitation.Command()
            {
                EnrollmentId         = enrollment.Id.GetGuid(),
                CommunicationChannel = CommunicationChannel.OutgoingPersonalContact,
                AdditionalNotes      = "brak notatek",
                SelectedTrainingID   = 1
            },
                recordingCoordinator,
                new[] { training },
                NodaTime.SystemClock.Instance.GetCurrentInstant());

            // Assert
            Assert.False(result.IsSuccess);
            var error = Assert.IsType <Error.DomainError>(result.Error);

            Assert.Equal(RecordAcceptedTrainingInvitation_ErrorMessages.TrainingTimeAlreadyPassed, error.Message);
        }
        public void After_registering_training_invitation_refusal_enrollment_aggregate_contains_additional_notes()
        {
            // Arrange
            var id     = EnrollmentAggregate.EnrollmentId.New;
            var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>(
                new RecruitmentFormSubmitted(
                    NodaTime.SystemClock.Instance.GetCurrentInstant(),
                    "Andrzej", "Strzelba",
                    EmailAddress.Parse("*****@*****.**"), Consts.FakePhoneNumber,
                    "ala ma kota", 1, "małopolskie", new[] { "Wadowice" }, new[] { 1 }, true),
                new Metadata(),
                DateTimeOffset.Now,
                id,
                1);
            var enrollment = new EnrollmentAggregate(id);

            enrollment.ApplyEvents(new[] { event1 });

            var training             = CreateTrainingInFutureWithId(1);
            var recordingCoordinator = new Models.Users.ApplicationUser()
            {
                Id = Guid.NewGuid()
            };
            var command = new RecordAcceptedTrainingInvitation.Command()
            {
                EnrollmentId         = id.GetGuid(),
                CommunicationChannel = CommunicationChannel.OutgoingEmail,
                SelectedTrainingID   = 1,
                AdditionalNotes      = "brak notatek"
            };

            // Act
            var result = enrollment.RecordCandidateAcceptedTrainingInvitation(command, recordingCoordinator, new[] { training }, NodaTime.SystemClock.Instance.GetCurrentInstant());

            // Assert
            // Assert
            Assert.True(result.IsSuccess);
            Assert.Contains("brak notatek", enrollment.AdditionalNotes);
        }