public async Task WhenTheInnerHandlerThrowsAHandledExceptionAndTheNumberOfretriesIsExceeded_ThenTheOriginalExceptionIsRethrown(Type exceptionType, string retryKey) { // arrange var errorMessage = exceptionType.ToString(); var testException = (Exception)Activator.CreateInstance(exceptionType, errorMessage); Exception caughtException = null; _testQueueMessage.UserProperties[retryKey] = _maxRetryAttempts; var command = new SendSmsCommand(_testOutgoingSms, _testQueueMessage); _mockHandler .Setup(m => m.HandleAsync(command, It.IsAny <CancellationToken>())) .ThrowsAsync(testException); // act try { await _sut.HandleAsync(command); } catch (Exception ex) { caughtException = ex; } caughtException.Should().BeOfType(exceptionType); }
public async Task WhenCalled_ThenTheConversationIsSavedToTheConversationRepository() { // arrange Conversation testConversation = null; OutgoingSms message = new OutgoingSmsBuilder(); _mockConversationRepository.Setup(m => m.Save(It.IsAny <Conversation>())) .Callback <Conversation>(c => { c.Id.Should().Be(message.Conversation.ConversationId); c.ActivityId.Should().Be(message.Conversation.ActivityId); c.TurnId.Should().Be(message.Conversation.TurnId); testConversation = c; }) .Returns(Task.CompletedTask); var command = new SendSmsCommand(message, _testQueueMessage); // act await _sut.HandleAsync(command); //assert _mockConversationRepository.Verify(m => m.Save(testConversation), Times.Once); }
public async Task When_UserHasEnoughSmsLimit_SmsEventIsPushed() { using (var testServer = await CreateWithUserAsync()) { //Add Some SMS Credits var dbContext = testServer.Host.Services.GetService(typeof(ApplicationDbContext)) as ApplicationDbContext; var subjectId = (testServer.Host.Services .GetRequiredService(typeof(Claim)) as Claim).Value; var user = await dbContext.Users.FirstAsync(u => u.SubjectId == subjectId); user.AddSmsBalance(2); await dbContext.SaveChangesAsync(); var messages = new List <SmsMessageModel>(); for (var i = 0; i < 2; i++) { messages.Add(new SmsMessageModel("5544567788", "TEST", "TEST")); } var command = new SendSmsCommand(Guid.NewGuid(), messages); var response = await testServer.CreateClient().PostAsync(ApiPath, command.ToJsonContent()); response.EnsureSuccessStatusCode(); var @event = Consumer.Instance.GetFirst <ISendSmsRequestReceived>(); @event.UserId.Should().NotBe(default);
public async Task When_UserHasEnoughSmsLimit_SmsEventIsPushed() { using var testServer = await CreateWithUserAsync(); var user = await testServer.GetCurrentUserInSession(); var client = testServer.CreateClient(); var addSmsCreditsCommand = new AddSmsCreditsCommand(Guid.NewGuid(), user.Id, 2, false); await client.PostAsync($"{ApiPath}/add-credits", addSmsCreditsCommand.ToJsonContent()); var messages = new List <SmsMessageModel>(); for (var i = 0; i < 2; i++) { messages.Add(new SmsMessageModel("5544567788", "TEST", "TEST")); } var command = new SendSmsCommand(Guid.NewGuid(), messages); var response = await client.PostAsync(ApiPath, command.ToJsonContent()); response.EnsureSuccessStatusCode(); var @event = Consumer.Instance.GetFirst <ISendSmsRequestReceived>(); @event.UserId.Should().NotBe(default);
private void Handle(SmsNotificationJobContext context, UserCardBlocked cardBlocked) { var profile = VerifyProfile(context, cardBlocked.UserId); if (profile == null) { return; } if (!profile.SmsNotificationEnabled) { return; } var card = context.CardAccountService.GetCard(new IdentityQuery <Guid>(cardBlocked.Card.CardId)); if (card == null) { throw new InvalidOperationException("Can't find card."); } var secureCardNo = string.Format( "{0}****{1}", new string(card.CardNo.Take(8).ToArray()), new string(card.CardNo.Skip(12).ToArray())); var cardName = string.Format("{0}('{1}')", secureCardNo, cardBlocked.Card.FriendlyName ?? cardBlocked.Card.CardVendor.Name); var sms = new SendSmsCommand { RecipientPhoneNumber = profile.PhoneNumber, Text = string.Format(SmsMessages.CardBlocked, cardName) }; context.SmsService.SendSms(sms); }
public async Task WhenTheInnerHandlerThrowsAHandledException_ThenADelayedMessageHasItsExistingRetryPropertiesClearedBeforeSettingTheRetryCount(Type exceptionType, string retryKey) { // arrange var errorMessage = Guid.NewGuid().ToString(); var testException = (Exception)Activator.CreateInstance(exceptionType, errorMessage); _maxRetryAttempts = 3; _testQueueMessage.UserProperties["ConversationLockedRetryCount"] = _maxRetryAttempts - 1; _testQueueMessage.UserProperties["OutOfOrderRetryCount"] = _maxRetryAttempts - 1; _testQueueMessage.UserProperties["PreviousMessageNotSentCount"] = _maxRetryAttempts - 1; var command = new SendSmsCommand(_testOutgoingSms, _testQueueMessage); _mockHandler .Setup(m => m.HandleAsync(command, It.IsAny <CancellationToken>())) .ThrowsAsync(testException); // act await _sut.HandleAsync(command); //assert var existingProperties = _testQueueMessage.UserProperties.ToList().Where(i => !i.Key.Equals(retryKey)); existingProperties.Count().Should().Be(0); }
public async Task WhenCalled_ThenTheSmsIsSentUsingToTheNotificationClient() { // arrange var mobileNumber = Guid.NewGuid().ToString(); var messageText = Guid.NewGuid().ToString(); var reference = Guid.NewGuid().ToString(); var message = new OutgoingSmsBuilder() .WithConversation(new BotConversationBuilder().WithConversationId(reference)) .WithMessageText(messageText) .WithParticipant(new ParticipantBuilder().WithUserId(mobileNumber)); var command = new SendSmsCommand(message, _testQueueMessage); // act await _sut.HandleAsync(command); //assert _mockNotificationClient.Verify(m => m.SendSms( mobileNumber, _testNotifyTemplateId, It.Is <Dictionary <string, dynamic> >(i => i.ContainsKey("message") && i.ContainsValue(messageText)), reference, _testNotifySmsSenderId) , Times.Once); }
public async Task <CommandHandlingResult> Handle(SendSmsCommand command, IEventPublisher eventPublisher) { var message = await _smsRepository.GetAsync(command.Id); var msg = new { Phone = command.Phone.SanitizePhone(), command.Id, command.Provider, command.CountryCode }; if (message == null) { _log.WriteInfo(nameof(SendSmsCommand), msg, $"Sms message with messageId = {command.Id} not found"); return(CommandHandlingResult.Ok()); } if (message.IsExpired(_smsSettings.SmsRetryTimeout)) { await _smsRepository.DeleteAsync(message.Id, message.MessageId); _log.WriteInfo(nameof(SendSmsCommand), msg, "Sms message expired and has been deleted"); return(CommandHandlingResult.Ok()); } var sender = _smsSenderFactory.GetSender(command.Provider); _log.WriteInfo(nameof(SendSmsCommand), msg, "Sending sms"); try { string messageId = await sender.SendSmsAsync(command.Phone, command.Message, command.CountryCode); if (!string.IsNullOrEmpty(messageId)) { await _smsRepository.SetMessageIdAsync(messageId, command.Id); _log.WriteInfo(nameof(SendSmsCommand), new { command.Id, MessageId = messageId }, "Message has been sent"); } else { await _smsRepository.DeleteAsync(command.Id, messageId); _log.WriteInfo(nameof(SendSmsCommand), new { command.Id }, "Sms message has been deleted"); } } catch (Exception) { await _smsProviderInfoRepository.AddAsync(command.Provider, command.CountryCode, SmsDeliveryStatus.Failed); return(CommandHandlingResult.Fail(_smsSettings.SmsSendDelay)); } return(CommandHandlingResult.Ok()); }
public void CanSendSms_WithoutExceptions() { var smsService = Scope.Resolve <ISmsService>(); var sms = new SendSmsCommand { RecipientPhoneNumber = "+375293593295", Text = "SMS Service Test" }; smsService.SendSms(sms); }
public async Task WhenCalled_ThenLatestConversationIsRetrievedFromtherepository() { // arrange var command = new SendSmsCommand(_testOutgoingSms, _testQueueMessage); // act await _sut.HandleAsync(command); //assert _mockConversationRepository.Verify(m => m.Get(_testOutgoingSms.Conversation.ConversationId), Times.Once); }
public async Task WhenCalled_ThenInnerHandlerIsCalled() { // arrange var command = new SendSmsCommand(_testOutgoingSms, _testQueueMessage); // act await _sut.HandleAsync(command); //assert _mockHandler.Verify(m => m.HandleAsync(command, It.IsAny <CancellationToken>()), Times.Once); }
public async Task SendSms([FromBody] SendSmsRequest request) { var message = new SendSmsCommand { Message = request.Message, Mobile = request.Mobile }; await _rabbitConnector.RaiseEventAsync(new SendSmsEvent { Payload = message.ObjectSerializer(), RoutingKey = "RabbitMq_Consumer", EndpointId = SystemConstants.HostEndpointId }); }
public async Task Handle(SmsProviderProcessed evt, ICommandSender commandSender) { _log.WriteInfo(nameof(SmsProviderProcessed), new { Phone = evt.Phone.SanitizePhone(), evt.Id, evt.Provider, evt.CountryCode }, "Sms processed"); var sendSmsCommand = new SendSmsCommand { Phone = evt.Phone, Message = evt.Message, Provider = evt.Provider, CountryCode = evt.CountryCode, Id = evt.Id }; commandSender.SendCommand(sendSmsCommand, "sms"); }
public void WhenTheNotificationClientThrowsAnException_ThenTheConversationIsNotSavedTotheConverssationRepository() { // arrange _mockNotificationClient.Setup(m => m.SendSms(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Dictionary <string, dynamic> >(), It.IsAny <string>(), It.IsAny <string>())) .ThrowsAsync(new Exception()); var command = new SendSmsCommand(new OutgoingSmsBuilder(), _testQueueMessage); // act Func <Task> action = async() => await _sut.HandleAsync(command); //assert action.Should().ThrowExactly <Exception>(); _mockConversationRepository.Verify(m => m.Save(It.IsAny <Conversation>()), Times.Never); }
public async Task When_UsersLimitNotEnoughToSendSms_InsufficientFundError_Should_BeReturned() { using var testServer = await CreateWithUserAsync(); var client = testServer.CreateClient(); var messages = new List <SmsMessageModel>(); for (var i = 0; i < 100; i++) { messages.Add(new SmsMessageModel("5544567788", "TEST", "TEST")); } var command = new SendSmsCommand(Guid.NewGuid(), messages); var response = await client.PostAsync(ApiPath, command.ToJsonContent()); await response.Should().BeBadRequestAsync(ErrorCodes.InsufficientFunds); }
public async Task WhenTheInnerHandlerThrowsAHandledException_ThenTheDelayIsLogged(Type exceptionType) { // arrange var errorMessage = Guid.NewGuid().ToString(); var testException = (Exception)Activator.CreateInstance(exceptionType, errorMessage); var command = new SendSmsCommand(_testOutgoingSms, _testQueueMessage); _mockHandler .Setup(m => m.HandleAsync(command, It.IsAny <CancellationToken>())) .ThrowsAsync(testException); // act await _sut.HandleAsync(command); //assert _mockLogger.Verify(m => m.Log(LogLevel.Information, 0, It.Is <FormattedLogValues>(l => l[0].Value.Equals($"{testException.Message} Delaying the processing for this message.")), null, It.IsAny <Func <object, Exception, string> >()), Times.Once); }
public void WhenTheInnerHandlerThrowsAnUnhandledException_ThenExceptionIsPropogated() { // arrange var errorMessage = Guid.NewGuid().ToString(); var testException = new Exception(errorMessage); var command = new SendSmsCommand(_testOutgoingSms, _testQueueMessage); _mockHandler .Setup(m => m.HandleAsync(command, It.IsAny <CancellationToken>())) .ThrowsAsync(testException); // act Func <Task> action = async() => await _sut.HandleAsync(command); //assert action.Should().ThrowExactly <Exception>().WithMessage(errorMessage); }
public async Task WhenTheInnerHandlerThrowsAHandledException_ThenADelayedMessageIsSentToTheQueue(Type exceptionType, string retryKey) { // arrange var errorMessage = Guid.NewGuid().ToString(); var testException = (Exception)Activator.CreateInstance(exceptionType, errorMessage); var command = new SendSmsCommand(_testOutgoingSms, _testQueueMessage); _mockHandler .Setup(m => m.HandleAsync(command, It.IsAny <CancellationToken>())) .ThrowsAsync(testException); // act await _sut.HandleAsync(command); //assert _mockQueueClient.Verify(m => m.SendAsync(It.Is <Message>((qm) => ((int)qm.UserProperties[retryKey]) == 1)), Times.Once); }
public async Task Handle(SmsMessageDeliveryFailed evt, ICommandSender commandSender) { _log.WriteInfo(nameof(SmsMessageDeliveryFailed), new { Phone = evt.Message.Phone.SanitizePhone(), evt.Message.Id, evt.Message.Provider, evt.Message.CountryCode }, $"Retrying sms delivery. Sending using {evt.Message.Provider.ToString()}, country code: {evt.Message.CountryCode}"); var sendSmsCommand = new SendSmsCommand { Phone = evt.Message.Phone, Message = evt.Message.Message, Provider = evt.Message.Provider, CountryCode = evt.Message.CountryCode, Id = evt.Message.Id }; commandSender.SendCommand(sendSmsCommand, "sms"); }
public async Task WhenTheConversationHasAlreadyBeenStartedAndTheCommandIsInOrder_ThenTheInnerHandlerIsCalled() { // arrange Conversation lastConversation = new ConversationBuilder() .WithId(_testOutgoingSms.Conversation.ConversationId) .WithTurnId(2); _testOutgoingSms.Conversation.TurnId = lastConversation.TurnId + 1; var command = new SendSmsCommand(_testOutgoingSms, _testQueueMessage); _mockConversationRepository .Setup(m => m.Get(_testOutgoingSms.Conversation.ConversationId)) .ReturnsAsync(lastConversation); // act await _sut.HandleAsync(command); //assert _mockHandler.Verify(m => m.HandleAsync(command, It.IsAny <CancellationToken>()), Times.Once); }
private void Handle(SmsNotificationJobContext context, SmsCodeCreated smsCodeCreated) { var profile = VerifyProfile(context, smsCodeCreated.UserId); if (profile == null) { return; } if (!profile.SmsConfirmationEnabled) { Logger.Error("Sms code was created for user with sms confirmation feature disabled."); return; } var sms = new SendSmsCommand { RecipientPhoneNumber = profile.PhoneNumber, Text = string.Format(SmsMessages.SecurityCode, smsCodeCreated.Code) }; context.SmsService.SendSms(sms); }
public async Task WhenTheTurnIdIsThesameAsTheCurentOne_ThenTheInnerHandlerIsNotCalled() { // arrange Conversation lastConversation = new ConversationBuilder() .WithId(_testOutgoingSms.Conversation.ConversationId) .WithTurnId(2); _testOutgoingSms.Conversation.TurnId = lastConversation.TurnId; var command = new SendSmsCommand(_testOutgoingSms, _testQueueMessage); _mockConversationRepository .Setup(m => m.Get(_testOutgoingSms.Conversation.ConversationId)) .ReturnsAsync(lastConversation); // act await _sut.HandleAsync(command); //assert _mockHandler.Verify(m => m.HandleAsync(command, It.IsAny <CancellationToken>()), Times.Never); }
public void WhenTheTurnIdIsOutOfOrder_ThenAnOutOfOrderExceptionIscalled() { // arrange Conversation lastConversation = new ConversationBuilder() .WithId(_testOutgoingSms.Conversation.ConversationId) .WithTurnId(3); _testOutgoingSms.Conversation.TurnId = lastConversation.TurnId + 2; var command = new SendSmsCommand(_testOutgoingSms, _testQueueMessage); _mockConversationRepository .Setup(m => m.Get(_testOutgoingSms.Conversation.ConversationId)) .ReturnsAsync(lastConversation); // act Func <Task> action = async() => await _sut.HandleAsync(command); //assert action.Should().ThrowExactly <OutOfOrderException>().WithMessage($"Message for conversation {_testOutgoingSms.Conversation.ConversationId} processed out of order. Expected turnId {lastConversation.TurnId + 1} but received turnId {command.Message.Conversation.TurnId} with activityId {command.Message.Conversation.ActivityId}"); }
public void WhenTheTurnIdIsOutOfOrder_ThenTheInnerHandlerIsNotCalled() { // arrange Conversation lastConversation = new ConversationBuilder() .WithId(_testOutgoingSms.Conversation.ConversationId) .WithTurnId(3); _testOutgoingSms.Conversation.TurnId = lastConversation.TurnId + 2; var command = new SendSmsCommand(_testOutgoingSms, _testQueueMessage); _mockConversationRepository .Setup(m => m.Get(_testOutgoingSms.Conversation.ConversationId)) .ReturnsAsync(lastConversation); // act Func <Task> action = async() => await _sut.HandleAsync(command); action.Invoke(); //assert _mockHandler.Verify(m => m.HandleAsync(It.IsAny <SendSmsCommand>(), It.IsAny <CancellationToken>()), Times.Never); }
public void SendSms(SendSmsCommand command) { EnsureIsValid(command); try { if (_settings.UseLogger) { var smsModel = new SmsModel { From = _settings.OutboundPhoneNumber, Text = command.Text, To = command.RecipientPhoneNumber }; _deps.SmsLogger.Log(smsModel); } var client = _deps.TwilioClientFactory.Create(); client.SendSmsMessage(_settings.OutboundPhoneNumber, command.RecipientPhoneNumber, command.Text); } catch (Exception ex) { throw new ServiceException("Can't send sms.", ex); } }
public Result SendSms(SendSmsCommand sendSmsCommand) { throw new NotImplementedException(); }
private void Handle(SmsNotificationJobContext context, TransactionProcessedEvent smsEvent) { var transaction = context.ProcessingService.GetCardTransaction(new IdentityQuery <Guid>(smsEvent.TransactionId)); if (transaction == null) { return; } if (transaction.Status == ProcessStatusModel.Pending) { return; } var account = context.CardAccountService.GetCardAccountBrief(new IdentityQuery <string>(transaction.AccountNo)); if (account == null) { Logger.Info("Couldn't find account for card transaction #{0}.", smsEvent.TransactionId); return; } var profile = VerifyProfile(context, account.Owner.UserId); if (profile == null || !profile.SmsNotificationEnabled) { return; } var sms = new SendSmsCommand { RecipientPhoneNumber = profile.PhoneNumber }; var secureCardNo = string.Format( "{0}****{1}", new string(transaction.CardNo.Take(8).ToArray()), new string(transaction.CardNo.Skip(12).ToArray())); if (transaction.Status == ProcessStatusModel.Failed) { var message = string.Format( SmsMessages.CardError, secureCardNo, string.Format("{0:F2} {1}", transaction.TransactionAmount, transaction.Currency.ISOName), transaction.Location, TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, _timezone), string.Format("{0:F2} {1}", account.Balance, account.Currency.ISOName)); sms.Text = message; context.SmsService.SendSms(sms); return; } if (transaction.TransactionAmount < 0) { var message = string.Format( SmsMessages.CardWithdrawal, secureCardNo, string.Format("{0:F2} {1}", -transaction.TransactionAmount, transaction.Currency.ISOName), transaction.Location, TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, _timezone), string.Format("{0:F2} {1}", account.Balance, account.Currency.ISOName)); sms.Text = message; context.SmsService.SendSms(sms); } else { var message = string.Format( SmsMessages.CardDeposit, secureCardNo, string.Format("{0:F2} {1}", transaction.TransactionAmount, transaction.Currency.ISOName), transaction.Location, TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, _timezone), string.Format("{0:F2} {1}", account.Balance, account.Currency.ISOName)); sms.Text = message; context.SmsService.SendSms(sms); } }
public async Task <IActionResult> SendSmsAsync([FromBody, Required] SendSmsCommand command) { await _commandProcessor.SendAsync(command); return(Accepted()); }