public void Command_with_unknown_communication_channel_fails()
        {
            // Arrange
            var id                   = EnrollmentAggregate.EnrollmentId.New;
            var enrollment           = new EnrollmentAggregate(id);
            var recordingCoordinator = new ApplicationUser()
            {
                Id = Guid.NewGuid()
            };

            // Act
            var result = enrollment.RecordResignation(new RecordResignation.Command()
            {
                EnrollmentId         = id.GetGuid(),
                CommunicationChannel = CommunicationChannel.Unknown,
                ResignationReason    = "brak powodu",
                AdditionalNotes      = "notatka testowa",
                ResignationType      = RecordResignation.ResignationType.Permanent
            },
                                                      recordingCoordinator,
                                                      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(RecordResignation.Command.CommunicationChannel), failure.PropertyName);
            Assert.Single(failure.Errors);
        }
        public void Candidate_must_be_registered_to_resign()
        {
            // Arrange
            var id                   = EnrollmentAggregate.EnrollmentId.New;
            var enrollment           = new EnrollmentAggregate(id);
            var recordingCoordinator = new ApplicationUser()
            {
                Id = Guid.NewGuid()
            };
            var command = new RecordResignation.Command()
            {
                EnrollmentId         = id.GetGuid(),
                CommunicationChannel = CommunicationChannel.OutgoingEmail,
                ResignationReason    = "brak powodu",
                AdditionalNotes      = "brak notatek",
                ResignationType      = RecordResignation.ResignationType.Permanent
            };

            // Act
            var result = enrollment.RecordResignation(command, recordingCoordinator, NodaTime.SystemClock.Instance.GetCurrentInstant());

            // Assert
            Assert.True(result.IsFailure);
            var error = Assert.IsType <Error.ResourceNotFound>(result.Error);

            Assert.Equal(CommonErrorMessages.CandidateNotFound, error.Message);
        }
        public void If_candidate_has_resigned_temporarily_with_resume_date__then_aggregate_has_HasResignedTemporarily_flag_and_HasResignedEffectively_with_date_after_resuma_date_returns_true()
        {
            // 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, "Wolne Miasto Gdańsk", new[] { "Wadowice" }, new[] { 1 }, true),
                new Metadata(), DateTimeOffset.Now, id, 1
                );
            var enrollment = new EnrollmentAggregate(id);

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

            var recordingCoordinator = new ApplicationUser()
            {
                Id = Guid.NewGuid()
            };
            var currentDate = new NodaTime.LocalDate(2020, 06, 30);

            // Act
            var result = enrollment.RecordResignation(new RecordResignation.Command()
            {
                EnrollmentId         = id.GetGuid(),
                CommunicationChannel = CommunicationChannel.OutgoingEmail,
                ResignationReason    = "brak powodu",
                AdditionalNotes      = "notatka testowa",
                ResignationType      = RecordResignation.ResignationType.Temporary,
                ResumeDate           = currentDate.PlusWeeks(1)
            },
                                                      recordingCoordinator,
                                                      currentDate.AtStartOfDayInZone(Consts.MainTimezone).ToInstant());

            // Assert
            Assert.True(result.IsSuccess);
            var uncommittedEvent = Assert.Single(enrollment.UncommittedEvents, e => e.AggregateEvent is CandidateResignedTemporarily);
            var @event           = Assert.IsType <CandidateResignedTemporarily>(uncommittedEvent.AggregateEvent);

            Assert.Equal(recordingCoordinator.Id, @event.RecordingCoordinatorID);
            Assert.Equal(CommunicationChannel.OutgoingEmail, @event.CommunicationChannel);
            Assert.Equal("brak powodu", @event.ResignationReason);
            Assert.Equal("notatka testowa", @event.AdditionalNotes);
            Assert.Equal(currentDate.PlusWeeks(1), @event.ResumeDate);

            enrollment.HasResignedEffectively(currentDate.PlusWeeks(2).AtStartOfDayInZone(Consts.MainTimezone).ToInstant()).Should().BeFalse();
        }
        public void If_candidate_has_resigned_temporarily_without_resume_date__then_aggregate_contains_CandidateResignedTemporarily_event_without_resume_date()
        {
            // 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, "Wolne Miasto Gdańsk", new[] { "Wadowice" }, new[] { 1 }, true),
                new Metadata(), DateTimeOffset.Now, id, 1
                );
            var enrollment = new EnrollmentAggregate(id);

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

            var recordingCoordinator = new ApplicationUser()
            {
                Id = Guid.NewGuid()
            };

            // Act
            var result = enrollment.RecordResignation(new RecordResignation.Command()
            {
                EnrollmentId         = id.GetGuid(),
                CommunicationChannel = CommunicationChannel.OutgoingEmail,
                ResignationReason    = "brak powodu",
                AdditionalNotes      = "notatka testowa",
                ResignationType      = RecordResignation.ResignationType.Temporary,
                ResumeDate           = null
            },
                                                      recordingCoordinator,
                                                      NodaTime.SystemClock.Instance.GetCurrentInstant());

            // Assert
            Assert.True(result.IsSuccess);
            var uncommittedEvent = Assert.Single(enrollment.UncommittedEvents, e => e.AggregateEvent is CandidateResignedTemporarily);
            var @event           = Assert.IsType <CandidateResignedTemporarily>(uncommittedEvent.AggregateEvent);

            Assert.Equal(recordingCoordinator.Id, @event.RecordingCoordinatorID);
            Assert.Equal(CommunicationChannel.OutgoingEmail, @event.CommunicationChannel);
            Assert.Equal("brak powodu", @event.ResignationReason);
            Assert.Equal("notatka testowa", @event.AdditionalNotes);
            Assert.Null(@event.ResumeDate);
        }
        public void ResumeDate_cannot_be_earlier_than_today()
        {
            // 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, "Wolne Miasto Gdańsk", new[] { "Wadowice" }, new[] { 1 }, true),
                new Metadata(), DateTimeOffset.Now, id, 1
                );
            var enrollment = new EnrollmentAggregate(id);

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

            var recordingCoordinator = new ApplicationUser()
            {
                Id = Guid.NewGuid()
            };
            var currentDate = new NodaTime.LocalDate(2020, 06, 30);

            // Act
            var result = enrollment.RecordResignation(new RecordResignation.Command()
            {
                EnrollmentId         = id.GetGuid(),
                CommunicationChannel = CommunicationChannel.IncomingEmail,
                ResignationReason    = "brak powodu",
                AdditionalNotes      = "notatka testowa",
                ResignationType      = RecordResignation.ResignationType.Temporary,
                ResumeDate           = currentDate.Minus(Period.FromDays(1))
            },
                                                      recordingCoordinator,
                                                      currentDate.AtStartOfDayInZone(Consts.MainTimezone).ToInstant());

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

            error.Message.Should().BeEquivalentTo(RecordResignation_Messages.ResumeDateCannotBeEarlierThanToday);
        }
        public void If_candidate_has_resigned_permanently_then_aggregate_HasResigned_flag_is_set()
        {
            // 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, "Wolne Miasto Gdańsk", new[] { "Wadowice" }, new[] { 1 }, true),
                new Metadata(), DateTimeOffset.Now, id, 1
                );
            var enrollment = new EnrollmentAggregate(id);

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

            var recordingCoordinator = new ApplicationUser()
            {
                Id = Guid.NewGuid()
            };

            // Act
            var result = enrollment.RecordResignation(new RecordResignation.Command()
            {
                EnrollmentId         = id.GetGuid(),
                CommunicationChannel = CommunicationChannel.OutgoingEmail,
                ResignationReason    = "brak powodu",
                AdditionalNotes      = "notatka testowa",
                ResignationType      = RecordResignation.ResignationType.Permanent,
            },
                                                      recordingCoordinator,
                                                      NodaTime.SystemClock.Instance.GetCurrentInstant());

            // Assert
            Assert.True(result.IsSuccess);
            Assert.True(enrollment.HasResignedPermanently);
        }