public void Command_with_invalid_CommunicationChannel_fails(CommunicationChannel communicationChannel) { // Arrange var id = EnrollmentAggregate.EnrollmentId.New; var enrollment = new EnrollmentAggregate(id); var recordingCoordinator = new Models.Users.ApplicationUser() { Id = Guid.NewGuid() }; var training = CreateTrainingWithIdAndDaysOffset(1, 1); var command = new RecordRefusedTrainingInvitation.Command() { EnrollmentId = id.GetGuid(), CommunicationChannel = communicationChannel }; // Act var result = enrollment.RecordCandidateRefusedTrainingInvitation( command, recordingCoordinator, new[] { training }, 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.CommunicationChannel), failure.PropertyName); Assert.Single(failure.Errors); }
public void Candidate_must_be_registered_to_decline_training_invitation() { // Arrange var id = EnrollmentAggregate.EnrollmentId.New; var enrollment = new EnrollmentAggregate(id); var recordingCoordinator = new Models.Users.ApplicationUser() { Id = Guid.NewGuid() }; var command = new RecordRefusedTrainingInvitation.Command() { EnrollmentId = id.GetGuid(), CommunicationChannel = CommunicationChannel.OutgoingPersonalContact, RefusalReason = "brak powodu", AdditionalNotes = "brak notatek" }; // Act var result = enrollment.RecordCandidateRefusedTrainingInvitation( command, recordingCoordinator, Array.Empty <Training>(), SystemClock.Instance.GetCurrentInstant()); // Assert Assert.True(result.IsFailure); var error = Assert.IsType <Szlem.Domain.Error.ResourceNotFound>(result.Error); Assert.Equal(CommonErrorMessages.CandidateNotFound, error.Message); }
public async Task <Result <Nothing, Error> > Handle(RecordRefusedTrainingInvitation.Command request, CancellationToken cancellationToken) { var user = await _userAccessor.GetUser(); var enrollment = await _aggregateStore.LoadAsync <EnrollmentAggregate, EnrollmentId>(EnrollmentId.With(request.EnrollmentId), cancellationToken); var preferredTrainings = await _trainingRepository.GetByIds(enrollment.PreferredTrainingIds); var result = await _aggregateStore.Update <EnrollmentAggregate, EnrollmentId, Result <Nothing, Error> >( EnrollmentId.With(request.EnrollmentId), CommandId.New, (aggregate) => aggregate.RecordCandidateRefusedTrainingInvitation(request, user, preferredTrainings, _clock.GetCurrentInstant()), cancellationToken); return(result.Unwrap()); }
// 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 Command_without_EnrollmentID_fails() { // Arrange var id = EnrollmentAggregate.EnrollmentId.New; var enrollment = new EnrollmentAggregate(id); var recordingCoordinator = new Models.Users.ApplicationUser() { Id = Guid.NewGuid() }; var training = CreateTrainingWithIdAndDaysOffset(1, 1); var command = new RecordRefusedTrainingInvitation.Command() { CommunicationChannel = CommunicationChannel.OutgoingEmail }; // Act & Assert var ex = Assert.Throws <AggregateMismatchException>(() => enrollment.RecordCandidateRefusedTrainingInvitation( command, recordingCoordinator, new[] { training }, SystemClock.Instance.GetCurrentInstant())); }
public Result <Nothing, Error> RecordCandidateRefusedTrainingInvitation( RecordRefusedTrainingInvitation.Command command, ApplicationUser recordingCoordinator, IReadOnlyCollection <Training> preferredTrainings, Instant currentInstant) { Guard.Against.Null(command, nameof(command)); Guard.Against.Null(recordingCoordinator, nameof(recordingCoordinator)); Guard.Against.Null(preferredTrainings, nameof(preferredTrainings)); Guard.Against.Default(currentInstant, nameof(currentInstant)); ValidateIdMatchOrThrow(command.EnrollmentId); return (Validate(new RecordRefusedTrainingInvitation.Validator(), command) .Ensure(_ => CanRefuseTrainingInvitation(preferredTrainings, currentInstant)) .Tap(_ => Emit(new CandidateRefusedTrainingInvitation( recordingCoordinatorID: recordingCoordinator.Id, communicationChannel: command.CommunicationChannel, refusalReason: command.RefusalReason ?? string.Empty, additionalNotes: command.AdditionalNotes ?? string.Empty)))); }
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 async Task <IActionResult> RecordRefusedTrainingInvitation(RecordRefusedTrainingInvitation.Command command) { var result = await _engine.Execute(command); return(result.MatchToActionResult(success => Ok())); }