public void Command_is_invalid_if_candidate_was_not_invited() { // 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 command = new SendTrainingReminder.Command() { EnrollmentId = id.GetGuid(), TrainingId = 1 }; var training = CreateTrainingWithIdAndOffset(1, Duration.FromHours(12)); // Act var result = enrollment.CanSendTrainingReminder(command, training, SystemClock.Instance.GetCurrentInstant()); // Assert result.IsSuccess.Should().BeFalse(); var error = result.Error.Should().BeOfType <Error.DomainError>().Subject; error.Message.Should().Be(SendTrainingReminder_Messages.Reminder_cannot_be_sent_if_the_candidate_is_not_invited_to_training); }
public void Training_passed_to_command_must_have_the_same_ID_as_preferred_training_or_command_throws() { // Arrange var training = BuildTraining(new NodaTime.LocalDateTime(2019, 09, 01, 10, 00), new NodaTime.LocalDateTime(2019, 09, 01, 12, 00), 1); 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 & Assert var ex = Assert.Throws <InvalidOperationException>(() => enrollment.RecordTrainingResults(new RecordTrainingResults.Command() { EnrollmentId = id.GetGuid(), TrainingId = 2, AdditionalNotes = "brak notatek", TrainingResult = RecordTrainingResults.TrainingResult.PresentAndAcceptedAsLecturer }, recordingCoordinator, new[] { training }, training, NodaTime.SystemClock.Instance.GetCurrentInstant())); }
public void With_valid_command__CanSendTrainingReminder_returns_success() { // Arrange var id = EnrollmentAggregate.EnrollmentId.New; var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>( new RecruitmentFormSubmitted( 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 event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>( new CandidateAcceptedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, 1, string.Empty), new Metadata(), DateTimeOffset.Now, id, 2 ); var enrollment = new EnrollmentAggregate(id); enrollment.ApplyEvents(new IDomainEvent[] { event1, event2 }); var command = new SendTrainingReminder.Command() { EnrollmentId = id.GetGuid(), TrainingId = 1 }; var training = CreateTrainingWithIdAndOffset(1, Duration.FromHours(12)); // Act var result = enrollment.CanSendTrainingReminder(command, training, SystemClock.Instance.GetCurrentInstant()); // Assert result.IsSuccess.Should().BeTrue(); }
public async Task After_command_is_executed__if_email_service_encounters_error__aggregate_contains_EmailSendingFailed_event() { // Arrange var enrollmentId = EnrollmentAggregate.EnrollmentId.New; var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>( new RecruitmentFormSubmitted( 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, enrollmentId, 1 ); var event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>( new CandidateAcceptedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, 1, string.Empty), new Metadata(), DateTimeOffset.Now, enrollmentId, 2 ); var enrollment = new EnrollmentAggregate(enrollmentId); enrollment.ApplyEvents(new IDomainEvent[] { event1, event2 }); var aggregateStore = new MockAggregateStore <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId>(enrollment); var emailService = new FailingEmailService(); var options = Mock.Of <IOptions <Config> >(mock => mock.Value == new Config() { TrainingReminderEmail = new Config.EmailMessageConfig() { Subject = "przypomnienie o szkoleniu", Body = "przypominamy o szkoleniu" } }); // Act var training = CreateTrainingWithIdAndOffset(1, Duration.FromHours(12)); var trainingRepo = Mock.Of <ITrainingRepository>(repo => repo.GetById(1) == Task.FromResult(Maybe <Training> .From(training))); var handler = new SendTrainingReminderHandler(SystemClock.Instance, aggregateStore, trainingRepo, emailService, options, new FluidTemplateRenderer()); var command = new SendTrainingReminder.Command() { EnrollmentId = enrollmentId.GetGuid(), TrainingId = 1 }; var result = await handler.Handle(command, CancellationToken.None); // Assert result.IsSuccess.Should().BeTrue(); enrollment.UncommittedEvents.Should().ContainSingle().Which.AggregateEvent.Should().BeOfType <EmailSendingFailed>(); var newEvent = enrollment.UncommittedEvents.Single().AggregateEvent as EmailSendingFailed; newEvent.Subject.Should().Be("przypomnienie o szkoleniu"); newEvent.Body.Should().Be("przypominamy o szkoleniu"); emailService.FailedMessages.Should().ContainSingle(); var emailMessage = emailService.FailedMessages.Single(); emailMessage.Subject.Should().Be("przypomnienie o szkoleniu"); emailMessage.Body.Should().Be("przypominamy o szkoleniu"); emailMessage.To.Should().ContainSingle().Which.Should().Be(EmailAddress.Parse("*****@*****.**")); }
public void Command_cannot_be_issued_earlier_than_24h_before_training() { // 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 event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>( new CandidateAcceptedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, 1, string.Empty), new Metadata(), DateTimeOffset.Now, id, 2 ); var enrollment = new EnrollmentAggregate(id); enrollment.ApplyEvents(new IDomainEvent[] { event1, event2 }); var command = new SendTrainingReminder.Command() { EnrollmentId = id.GetGuid(), TrainingId = 1 }; var training = CreateTrainingWithIdAndOffset(1, Duration.FromDays(3)); // Act var result = enrollment.CanSendTrainingReminder(command, training, SystemClock.Instance.GetCurrentInstant()); // Assert result.IsSuccess.Should().BeFalse(); var error = result.Error.Should().BeOfType <Error.DomainError>().Subject; error.Message.Should().Be(SendTrainingReminder_Messages.Reminder_cannot_be_sent_earlier_than_24h_before_training); }
public async Task After_command_is_executed__email_is_sent_and_aggregate_contains_EmailSent_event() { // Arrange var enrollmentId = EnrollmentAggregate.EnrollmentId.New; var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>( new RecruitmentFormSubmitted( 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, enrollmentId, 1 ); var event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>( new CandidateAcceptedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, 1, string.Empty), new Metadata(), DateTimeOffset.Now, enrollmentId, 2 ); var enrollment = new EnrollmentAggregate(enrollmentId); enrollment.ApplyEvents(new IDomainEvent[] { event1, event2 }); var aggregateStore = new MockAggregateStore <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId>(enrollment); var training = CreateTrainingWithIdAndOffset(1, Duration.FromHours(12)); var trainingRepo = Mock.Of <ITrainingRepository>(repo => repo.GetById(1) == Task.FromResult(Maybe <Training> .From(training))); var emailService = new SucceedingEmailService(); var options = Mock.Of <IOptions <Config> >(mock => mock.Value == new Config() { TrainingReminderEmail = new Config.EmailMessageConfig() { Subject = "przypomnienie o szkoleniu", Body = "{{ Candidate.FullName }} przypominamy o szkoleniu w {{ Training.City }} w dniu {{ Training.StartDate }}" + " o godzinie {{ Training.StartTime }} trwającym {{ Training.Duration }} godzin!" } }); // Act var handler = new SendTrainingReminderHandler(SystemClock.Instance, aggregateStore, trainingRepo, emailService, options, new FluidTemplateRenderer()); var command = new SendTrainingReminder.Command() { EnrollmentId = enrollmentId.GetGuid(), TrainingId = 1 }; var result = await handler.Handle(command, CancellationToken.None); // Assert result.IsSuccess.Should().BeTrue(); enrollment.UncommittedEvents.Should().ContainSingle(); enrollment.UncommittedEvents.Single().AggregateEvent.Should().BeOfType <EmailSent>(); emailService.SentMessages.Should().ContainSingle(); emailService.SentMessages.Single().Should().BeEquivalentTo(new { Subject = "przypomnienie o szkoleniu", Body = $"Andrzej Strzelba przypominamy o szkoleniu w Wadowice w dniu {training.StartDateTime.Date}" + $" o godzinie {training.StartDateTime.TimeOfDay} trwającym {training.Duration.ToString("HH':'mm", null)} godzin!" }); }
public void Cannot_record_training_attendance_before_trainings_end() { // Arrange var training = new Training( "Papieska 21/37", "Wadowice", new NodaTime.LocalDateTime(2019, 09, 01, 10, 00).InMainTimezone().ToOffsetDateTime(), new NodaTime.LocalDateTime(2019, 09, 01, 12, 00).InMainTimezone().ToOffsetDateTime(), Guid.NewGuid() ); training.GetType().GetProperty(nameof(Training.ID)).SetValue(training, 1); 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 event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>( new CandidateAcceptedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, 1, string.Empty), new Metadata(), DateTimeOffset.Now, id, 2 ); var enrollment = new EnrollmentAggregate(id); enrollment.ApplyEvents(new IDomainEvent[] { event1, event2 }); var recordingCoordinator = new ApplicationUser() { Id = Guid.NewGuid() }; // Act var result = enrollment.RecordTrainingResults(new RecordTrainingResults.Command() { EnrollmentId = id.GetGuid(), TrainingId = 1, TrainingResult = RecordTrainingResults.TrainingResult.Absent, AdditionalNotes = "notatka testowa" }, recordingCoordinator, new[] { training }, training, new NodaTime.LocalDateTime(2019, 09, 01, 11, 00).InMainTimezone().ToInstant() ); // Assert Assert.False(result.IsSuccess); var error = Assert.IsType <Error.DomainError>(result.Error); Assert.Equal(RecordTrainingResults_Messages.CannotRecordTrainingAttendanceBeforeTrainingEnd, 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_accepted_and_then_refused_training_invitation_then_he_cannot_be_recorded_as_absent_on_that_training() { // 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 event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>( new CandidateAcceptedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, 1, string.Empty), new Metadata(), DateTimeOffset.Now, id, 2 ); var event3 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateRefusedTrainingInvitation>( new CandidateRefusedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, "kandydat nie ma czasu", string.Empty), new Metadata(), DateTimeOffset.Now, id, 3 ); var enrollment = new EnrollmentAggregate(id); enrollment.ApplyEvents(new IDomainEvent[] { event1, event2, event3 }); var recordingCoordinator = new ApplicationUser() { Id = Guid.NewGuid() }; // Act var result = enrollment.RecordTrainingResults(new RecordTrainingResults.Command() { EnrollmentId = id.GetGuid(), TrainingId = 1, TrainingResult = RecordTrainingResults.TrainingResult.Absent, AdditionalNotes = "notatka testowa" }, recordingCoordinator, new[] { BuildDefaultTraining() }, BuildDefaultTraining(), NodaTime.SystemClock.Instance.GetCurrentInstant()); // Assert Assert.False(result.IsSuccess); var error = Assert.IsType <Error.DomainError>(result.Error); Assert.Equal(RecordTrainingResults_Messages.CannotRecordCandidateAsAbsentIfTheyDidNotAcceptTrainingInvitation, error.Message); }
public void If_candidate_was_present_but_was_not_accepted_as_lecturer_then_command_must_contain_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, "Wolne Miasto Gdańsk", new[] { "Wadowice" }, new[] { 1 }, true), new Metadata(), DateTimeOffset.Now, id, 1 ); var event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>( new CandidateAcceptedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, 1, string.Empty), new Metadata(), DateTimeOffset.Now, id, 2 ); var enrollment = new EnrollmentAggregate(id); enrollment.ApplyEvents(new IDomainEvent[] { event1, event2 }); var recordingCoordinator = new ApplicationUser() { Id = Guid.NewGuid() }; // Act var result = enrollment.RecordTrainingResults(new RecordTrainingResults.Command() { EnrollmentId = id.GetGuid(), TrainingId = 1, TrainingResult = RecordTrainingResults.TrainingResult.PresentButNotAcceptedAsLecturer, AdditionalNotes = null }, recordingCoordinator, new[] { BuildDefaultTraining() }, BuildDefaultTraining(), NodaTime.SystemClock.Instance.GetCurrentInstant()); // Assert Assert.False(result.IsSuccess); var error = Assert.IsType <Error.ValidationFailed>(result.Error); var failure = Assert.Single(error.Failures); AssertHelpers.SingleError( nameof(RecordTrainingResults.Command.AdditionalNotes), RecordTrainingResults_Messages.IfCandidateWasNotAccepted_CommandMustContainExplanation, failure); }
public void If_candidate_was_absent_from_the_training_aggregate_contains_CandidateWasAbsentFromTraining_event() { // 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 event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>( new CandidateAcceptedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, 1, string.Empty), new Metadata(), DateTimeOffset.Now, id, 2 ); var enrollment = new EnrollmentAggregate(id); enrollment.ApplyEvents(new IDomainEvent[] { event1, event2 }); var recordingCoordinator = new ApplicationUser() { Id = Guid.NewGuid() }; // Act var result = enrollment.RecordTrainingResults(new RecordTrainingResults.Command() { EnrollmentId = id.GetGuid(), TrainingId = 1, TrainingResult = RecordTrainingResults.TrainingResult.Absent, AdditionalNotes = "notatka testowa" }, recordingCoordinator, new[] { BuildDefaultTraining() }, BuildDefaultTraining(), NodaTime.SystemClock.Instance.GetCurrentInstant()); // Assert Assert.True(result.IsSuccess); var uncommittedEvent = Assert.Single(enrollment.UncommittedEvents); var @event = Assert.IsType <CandidateWasAbsentFromTraining>(uncommittedEvent.AggregateEvent); Assert.Equal(recordingCoordinator.Id, @event.RecordingCoordinatorID); Assert.Equal(1, @event.TrainingID); Assert.Equal("notatka testowa", @event.AdditionalNotes); }
public void Cannot_accept_invitation_to_training_not_selected_as_preferred_training() { // 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 training1 = CreateTrainingInFutureWithId(1); var training2 = CreateTrainingInFutureWithId(2); 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[] { training1, training2 }, 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); var errorMessage = Assert.Single(failure.Errors); Assert.Equal(RecordAcceptedTrainingInvitation_ErrorMessages.TrainingWasNotSpecifiedAsPreferred, errorMessage); }
public void Cannot_accept_invitation_to_training_earlier_than_submission_date() { // Arrange var id = EnrollmentAggregate.EnrollmentId.New; var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>( new RecruitmentFormSubmitted( 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 = new Training( "Papieska 12/37", "Wadowice", SystemClock.Instance.GetOffsetDateTime().Minus(Duration.FromDays(7)), SystemClock.Instance.GetOffsetDateTime().Minus(Duration.FromDays(6)), Guid.NewGuid()); training.GetType().GetProperty(nameof(training.ID)).SetValue(training, 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.False(result.IsSuccess); var error = Assert.IsType <Error.DomainError>(result.Error); Assert.Equal(RecordAcceptedTrainingInvitation_ErrorMessages.TrainingTimeAlreadyPassed, error.Message); }
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); }
// PhoneNumber.Parse() takes ~1 second, WHY? because initial call to PhoneNumbers.PhoneNumberUtil.Parse() loads entire XML dictionary public void Registered_candidate_can_decline_training_invitation() { // Arrange var id = EnrollmentAggregate.EnrollmentId.New; var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>( new RecruitmentFormSubmitted( 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[] { event1 }); var recordingCoordinator = new Models.Users.ApplicationUser() { Id = Guid.NewGuid() }; var training = CreateTrainingWithIdAndDaysOffset(1, 1); // Act var command = new RecordRefusedTrainingInvitation.Command() { EnrollmentId = id.GetGuid(), CommunicationChannel = CommunicationChannel.OutgoingPersonalContact, RefusalReason = "brak powodu", AdditionalNotes = "brak notatek" }; var result = enrollment.RecordCandidateRefusedTrainingInvitation(command, recordingCoordinator, new[] { training }, SystemClock.Instance.GetCurrentInstant()); // Assert Assert.True(result.IsSuccess); var e = Assert.Single(enrollment.UncommittedEvents); var @event = Assert.IsType <CandidateRefusedTrainingInvitation>(e.AggregateEvent); Assert.Equal(recordingCoordinator.Id, @event.RecordingCoordinatorID); Assert.Equal(CommunicationChannel.OutgoingPersonalContact, @event.CommunicationChannel); Assert.Equal("brak powodu", @event.RefusalReason); Assert.Equal("brak notatek", @event.AdditionalNotes); }
public void Registered_candidate_can_accept_training_invitation() { // 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 command = new RecordAcceptedTrainingInvitation.Command() { EnrollmentId = id.GetGuid(), CommunicationChannel = CommunicationChannel.OutgoingEmail, SelectedTrainingID = 1, AdditionalNotes = "brak notatek" }; var recordingCoordinator = new Models.Users.ApplicationUser() { Id = Guid.NewGuid() }; // Act var result = enrollment.RecordCandidateAcceptedTrainingInvitation(command, recordingCoordinator, new[] { training }, NodaTime.SystemClock.Instance.GetCurrentInstant()); // Assert Assert.True(result.IsSuccess); var uncommittedEvent = Assert.Single(enrollment.UncommittedEvents); var @event = Assert.IsType <CandidateAcceptedTrainingInvitation>(uncommittedEvent.AggregateEvent); Assert.Equal(recordingCoordinator.Id, @event.RecordingCoordinatorID); Assert.Equal(CommunicationChannel.OutgoingEmail, @event.CommunicationChannel); Assert.Equal(1, @event.SelectedTrainingID); Assert.Equal("brak notatek", @event.AdditionalNotes); }
public void If_training_was_selected_cannot_refuse_training_invitation_after_that_training_has_started() { // Arrange var id = EnrollmentAggregate.EnrollmentId.New; var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>( new RecruitmentFormSubmitted( SystemClock.Instance.GetCurrentInstant(), "Andrzej", "Strzelba", EmailAddress.Parse("*****@*****.**"), Consts.FakePhoneNumber, "ala ma kota", 1, "Wolne Miasto Gdańsk", new[] { "Wadowice" }, new[] { 1, 2 }, true), new Metadata(), DateTimeOffset.Now, id, 1 ); var event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>( new CandidateAcceptedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, 1, 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() }; var training1 = CreateTrainingWithIdAndDaysOffset(1, -1); var training2 = CreateTrainingWithIdAndDaysOffset(2, -2); // Act var result = enrollment.RecordCandidateRefusedTrainingInvitation( new RecordRefusedTrainingInvitation.Command() { EnrollmentId = enrollment.Id.GetGuid(), CommunicationChannel = CommunicationChannel.OutgoingPersonalContact, AdditionalNotes = "brak notatek" }, recordingCoordinator, new[] { training1, training2 }, SystemClock.Instance.GetCurrentInstant()); // Assert Assert.False(result.IsSuccess); var error = Assert.IsType <Error.DomainError>(result.Error); Assert.Equal(RecordRefusedTrainingInvitation_ErrorMessages.SelectedTrainingHasAlreadyPassed, error.Message); }
public void After_accepting_invitation__HasSignedUpForTraining_is_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, "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 training = CreateTrainingInFutureWithId(1); 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 = training.ID }, recordingCoordinator, new[] { training }, NodaTime.SystemClock.Instance.GetCurrentInstant()); // Assert Assert.True(result.IsSuccess); Assert.True(enrollment.HasSignedUpForTraining(training)); }
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 AfterRegisteringContact_EnrollmentEmitsContactOccuredEvent() { // 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 recordingUser = new ApplicationUser() { Id = Guid.NewGuid() }; // Act var result = enrollment.RecordContact(new RecordContact.Command() { EnrollmentId = id.GetGuid(), CommunicationChannel = CommunicationChannel.OutgoingEmail, Content = "ala ma kota", AdditionalNotes = "notatka testowa" }, recordingUser); // Assert Assert.True(result.IsSuccess); var uncommittedEvent = Assert.Single(enrollment.UncommittedEvents, e => e.AggregateEvent is ContactOccured); var @event = Assert.IsType <ContactOccured>(uncommittedEvent.AggregateEvent); Assert.Equal(recordingUser.Id, @event.RecordingUserId); Assert.Equal(CommunicationChannel.OutgoingEmail, @event.CommunicationChannel); Assert.Equal("ala ma kota", @event.Content); Assert.Equal("notatka testowa", @event.AdditionalNotes); }
public void If_candidate_was_present_but_was_not_accepted_as_lecturer_then_he_has_no_permission_to_conduct_classes() { // 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 event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>( new CandidateAcceptedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, 1, string.Empty), new Metadata(), DateTimeOffset.Now, id, 2 ); var enrollment = new EnrollmentAggregate(id); enrollment.ApplyEvents(new IDomainEvent[] { event1, event2 }); var recordingCoordinator = new ApplicationUser() { Id = Guid.NewGuid() }; // Act var result = enrollment.RecordTrainingResults(new RecordTrainingResults.Command() { EnrollmentId = id.GetGuid(), TrainingId = 1, TrainingResult = RecordTrainingResults.TrainingResult.PresentButNotAcceptedAsLecturer, AdditionalNotes = "kandydat nie spełnia wymagań" }, recordingCoordinator, new[] { BuildDefaultTraining() }, BuildDefaultTraining(), NodaTime.SystemClock.Instance.GetCurrentInstant()); // Assert Assert.True(result.IsSuccess); Assert.False(enrollment.HasLecturerRights); }
public void Candidate_can_be_recorded_as_present_on_the_training_if_his_last_answer_to_invitation_was_negative(RecordTrainingResults.TrainingResult trainingResult) { // 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 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 ApplicationUser() { Id = Guid.NewGuid() }; // Act var result = enrollment.RecordTrainingResults(new RecordTrainingResults.Command() { EnrollmentId = id.GetGuid(), TrainingId = 1, TrainingResult = trainingResult, AdditionalNotes = "notatka testowa" }, recordingCoordinator, new[] { BuildDefaultTraining() }, BuildDefaultTraining(), NodaTime.SystemClock.Instance.GetCurrentInstant()); // Assert Assert.True(result.IsSuccess); enrollment.UncommittedEvents.Should().Contain(x => x.AggregateEvent.GetType() == typeof(CandidateAttendedTraining)); }
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_refusing_invitation__candidate_is_not_signed_up_for_training() { // Arrange var id = EnrollmentAggregate.EnrollmentId.New; var event1 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, RecruitmentFormSubmitted>( new RecruitmentFormSubmitted( 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 event2 = new DomainEvent <EnrollmentAggregate, EnrollmentAggregate.EnrollmentId, CandidateAcceptedTrainingInvitation>( new CandidateAcceptedTrainingInvitation(Guid.NewGuid(), CommunicationChannel.OutgoingEmail, 1, 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() }; var training = CreateTrainingWithIdAndDaysOffset(1, 1); // Act var command = new RecordRefusedTrainingInvitation.Command() { EnrollmentId = enrollment.Id.GetGuid(), CommunicationChannel = CommunicationChannel.OutgoingPersonalContact, RefusalReason = "brak powodu", AdditionalNotes = "brak notatek" }; var result = enrollment.RecordCandidateRefusedTrainingInvitation(command, recordingCoordinator, new[] { training }, SystemClock.Instance.GetCurrentInstant()); // Assert Assert.True(result.IsSuccess); enrollment.HasSignedUpForTraining(training).Should().BeFalse(); }
public void Candidate_must_have_been_invited_to_training_invitation_to_be_recorded_as_absent() { // 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.RecordTrainingResults(new RecordTrainingResults.Command() { EnrollmentId = id.GetGuid(), TrainingId = 1, AdditionalNotes = "brak notatek", TrainingResult = RecordTrainingResults.TrainingResult.Absent }, recordingCoordinator, new[] { BuildDefaultTraining() }, BuildDefaultTraining(), NodaTime.SystemClock.Instance.GetCurrentInstant()); // Assert Assert.False(result.IsSuccess); var error = Assert.IsType <Error.DomainError>(result.Error); Assert.Equal(RecordTrainingResults_Messages.CannotRecordCandidateAsAbsentIfTheyDidNotAcceptTrainingInvitation, error.Message); }
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); }