public async Task ExecuteAsync_When_TransporterNotFound_Then_TransporterNotFoundExceptionThrown()
        {
            // Arrange
            var mock = new MockNotificationService();
            var pendingNotifications = new INotificationData[]
            {
                new MockNotificationData()
            };

            var expectedNextSchedule = DateTime.UtcNow.AddSeconds(60);

            mock.MockNotificationRepository.Setup(x => x.GetPendingNotificationsAsync(It.Is <DateTime>(mock.ExpectedPendingNotificationsTimestampCheck), It.IsAny <int?>())).Returns(Task.FromResult <IEnumerable <INotificationData> >(pendingNotifications));

            // Act & Assert
            await Assert.ThrowsAsync <TransporterNotFoundException>(() => mock.Service.ExecuteAsync());

            // Assert
            mock.MockNotificationRepository.Verify(x => x.GetPendingNotificationsAsync(It.Is <DateTime>(mock.ExpectedPendingNotificationsTimestampCheck), It.IsAny <int?>()), Times.Once);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(pendingNotifications[0].Id,
                                                                      NotificationState.Processing,
                                                                      0,
                                                                      null,
                                                                      null),
                                                   Times.Once);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(pendingNotifications[0].Id,
                                                                      NotificationState.WaitingForRetry,
                                                                      1,
                                                                      It.IsAny <string>(),
                                                                      It.Is <DateTime>((value) => value >= expectedNextSchedule)),
                                                   Times.Once);
        }
Beispiel #2
0
 public void Publish(INotificationData notificationdata)
 {
     if (notificationdata == null)
     {
         throw new ArgumentNullException("Notification cannot be null");
     }
     return;
 }
Beispiel #3
0
        /// <summary>
        /// Flow to the notification, since is shows up until vanish
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public override IEnumerator NotificationFlow(INotificationData value)
        {
            if (_notifications.Count == 0)
            {
                yield break;
            }

            Notification notification = _notifications.Dequeue();

            notification.PopulateNotificationValues(value);
            notification.gameObject.SetActive(true);
        }
        public async Task ExecuteAsync_When_TransporterErrorsMaximumAmount_Then_NotificationUpdatedWithFailed()
        {
            // Arrange
            var mock = new MockNotificationService();

            mock.Options.MaximumRetryCount = 1;
            mock.SetupTransporters();
            var pendingNotifications = new INotificationData[]
            {
                new MockNotificationData()
                {
                    TransportType = mock.MockNotificationTransporter.Object.TransporterType,
                    RetryCount    = 1
                }
            };

            mock.MockNotificationRepository.Setup(x => x.GetPendingNotificationsAsync(It.Is <DateTime>(mock.ExpectedPendingNotificationsTimestampCheck), It.IsAny <int?>())).Returns(Task.FromResult <IEnumerable <INotificationData> >(pendingNotifications));

            var transporterErrors = new string[] { "error" };

            mock.MockNotificationTransporter.Setup(x => x.SendAsync(pendingNotifications[0].NotificationType, pendingNotifications[0].Recipients, pendingNotifications[0].Content))
            .Returns(Task.FromResult <IEnumerable <string> >(transporterErrors));

            // Act
            var result = await mock.Service.ExecuteAsync();

            // Assert
            Assert.Equal(0, result);
            mock.MockNotificationRepository.Verify(x => x.GetPendingNotificationsAsync(It.Is <DateTime>(mock.ExpectedPendingNotificationsTimestampCheck), It.IsAny <int?>()), Times.Once);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(pendingNotifications[0].Id,
                                                                      NotificationState.Processing,
                                                                      1,
                                                                      null,
                                                                      null),
                                                   Times.Once);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(pendingNotifications[0].Id,
                                                                      NotificationState.Failed,
                                                                      1,
                                                                      transporterErrors[0],
                                                                      null),
                                                   Times.Once);


            mock.MockNotificationTransporter.Verify(x => x.SendAsync(pendingNotifications[0].NotificationType,
                                                                     pendingNotifications[0].Recipients,
                                                                     pendingNotifications[0].Content),
                                                    Times.Once);
        }
        public async Task ExecuteAsync_When_TransporterSendReportsErrors_Then_NotificationUpdatedWithWaitingForRetry()
        {
            // Arrange
            var mock = new MockNotificationService();

            mock.SetupTransporters();
            var pendingNotifications = new INotificationData[]
            {
                new MockNotificationData()
                {
                    TransportType = mock.MockNotificationTransporter.Object.TransporterType
                }
            };

            var expectedNextSchedule = DateTime.UtcNow.AddSeconds(60);

            mock.MockNotificationRepository.Setup(x => x.GetPendingNotificationsAsync(It.Is <DateTime>(mock.ExpectedPendingNotificationsTimestampCheck), It.IsAny <int?>())).Returns(Task.FromResult <IEnumerable <INotificationData> >(pendingNotifications));

            var transporterErrors = new string[] { "error" };

            mock.MockNotificationTransporter.Setup(x => x.SendAsync(pendingNotifications[0].NotificationType, pendingNotifications[0].Recipients, pendingNotifications[0].Content))
            .Returns(Task.FromResult <IEnumerable <string> >(transporterErrors));

            // Act
            var result = await mock.Service.ExecuteAsync();

            // Assert
            Assert.Equal(0, result);
            mock.MockNotificationRepository.Verify(x => x.GetPendingNotificationsAsync(It.Is <DateTime>(mock.ExpectedPendingNotificationsTimestampCheck), It.IsAny <int?>()), Times.Once);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(pendingNotifications[0].Id,
                                                                      NotificationState.Processing,
                                                                      0,
                                                                      null,
                                                                      null),
                                                   Times.Once);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(pendingNotifications[0].Id,
                                                                      NotificationState.WaitingForRetry,
                                                                      1,
                                                                      transporterErrors[0],
                                                                      It.Is <DateTime>((value) => value >= expectedNextSchedule)),
                                                   Times.Once);


            mock.MockNotificationTransporter.Verify(x => x.SendAsync(pendingNotifications[0].NotificationType,
                                                                     pendingNotifications[0].Recipients,
                                                                     pendingNotifications[0].Content),
                                                    Times.Once);
        }
Beispiel #6
0
        public async Task SendAsync(
            string notificationName,
            INotificationData data            = null,
            EntityIdentifier entityIdentifier = null,
            NotificationSeverity severity     = NotificationSeverity.Info,
            long[] userIds         = null,
            long[] excludedUserIds = null)
        {
            Throw.IfArgumentNull(notificationName, nameof(notificationName));

            var notification = new NotificationInfo(_guidGenerator.Create())
            {
                NotificationName = notificationName,
                NotificationDataTypeAssemblyQualifiedName = data == null ? typeof(NotificationData).AssemblyQualifiedName : data.GetType().AssemblyQualifiedName,
                EntityTypeName = entityIdentifier?.Type.FullName,
                EntityTypeAssemblyQualifiedName = entityIdentifier?.Type.AssemblyQualifiedName,
                EntityId        = entityIdentifier?.Id.ToJsonString(),
                Severity        = severity,
                UserIds         = userIds.IsNullOrEmpty() ? null : userIds.Select(uid => uid).JoinAsString(","),
                ExcludedUserIds = excludedUserIds.IsNullOrEmpty() ? null : excludedUserIds.Select(uid => uid).JoinAsString(","),
                Data            = data?.ToJsonString(),
                DataTypeName    = data?.GetType().AssemblyQualifiedName
            };

            await _unitOfWorkManager.PerformAsyncUow(async() =>
            {
                await _notificationStore.InsertNotificationAsync(notification);

                // To get Id of the notification
                await _unitOfWorkManager.Current.SaveChangesAsync();

                if (userIds != null && userIds.Length <= MaxUserCountToDirectlySendANotification)
                {
                    // We can process the notification since there are not much receivers
                    await _notificationDistributer.DistributeAsync(notification.Id);
                }
                else
                {
                    await _backgroundJobManager
                    .EnqueueAsync <NotificationDistributerJob, NotificationDistributerJobArgs>(
                        new NotificationDistributerJobArgs(notification.Id));
                }
            });
        }
        public async Task ScheduleAsync_When_TransporterPresent_RecipientResolverReturnsObject_Then_NotificationSaved()
        {
            // Arrange
            var mock           = new MockNotificationService();
            var recipient      = new Recipient();
            var content        = new NotificationContent();
            var resolverResult = new ResolverResult()
            {
                ToAddress = "*****@*****.**"
            };

            var expectedAddedNotifications = new INotificationData[]
            {
                new MockNotificationData()
            };

            mock.SetupTransporters();
            mock.MockNotificationRecipientResolver.Setup(x => x.ResolveAsync(recipient, content, mock.MockNotificationTransporter.Object.TransporterType))
            .Returns(Task.FromResult <object>(resolverResult));


            mock.MockNotificationRepository.Setup(x => x.AddAsync(It.Is <IEnumerable <CreatableNotification> >((creatables) => creatables.Count() == 1 &&
                                                                                                               creatables.FirstOrDefault(item => item.TransportType == mock.MockNotificationTransporter.Object.TransporterType &&
                                                                                                                                         item.Recipients == resolverResult &&
                                                                                                                                         item.NotificationType == content.NotificationType &&
                                                                                                                                         item.Content == content) != null)))
            .Returns(Task.FromResult <IEnumerable <INotificationData> >(expectedAddedNotifications));

            // Act
            var result = await mock.Service.ScheduleAsync(content, recipient);

            // Assert
            Assert.Single(result);
            Assert.Equal(expectedAddedNotifications, result);

            mock.MockNotificationRecipientResolver.Verify(x => x.ResolveAsync(recipient, content, mock.MockNotificationTransporter.Object.TransporterType), Times.Once);
            mock.MockNotificationRepository.Verify(x => x.AddAsync(It.IsAny <IEnumerable <CreatableNotification> >()), Times.Once);
        }
        private async Task <NotifyStatus> NotifyAsync(INotificationData data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            bool wasSuccessful = false;
            var  failureDetail = String.Empty;

            try
            {
                await _repository.UpdateAsync(data.Id, NotificationState.Processing, data.RetryCount, data.FailureDetail, data.NextExecutionTimestamp);

                var transporter = _manager.Get(data.TransportType);
                if (transporter == null)
                {
                    throw new TransporterNotFoundException(data.TransportType);
                }

                var errors = await transporter.SendAsync(data.NotificationType, data.Recipients, data.Content);

                wasSuccessful = errors?.Any(x => String.IsNullOrEmpty(x) == false) != true;
                failureDetail = errors?.Any() == true?errors?.Aggregate((current, next) => $"{current}. {next}") : null;
            }
            catch (System.Exception ex)
            {
                if (ex is TransporterNotFoundException)
                {
                    throw;
                }

                failureDetail = ex.Message;
            }
            finally
            {
                data.State = wasSuccessful ? NotificationState.Successful : NotificationState.Failed;
                DateTime?nextExecutionTimestamp = null;

                if (wasSuccessful == false &&
                    (_options.MaximumRetryCount == null || data.RetryCount < _options.MaximumRetryCount))
                {
                    data.State = NotificationState.WaitingForRetry;
                    data.RetryCount++;

                    nextExecutionTimestamp = DateTime.UtcNow.AddSeconds(_options.RetryCoolDownInSeconds * data.RetryCount * _options.RetryCoolDownMagnitude);
                }

                await _repository.UpdateAsync(data.Id, data.State, data.RetryCount, failureDetail, nextExecutionTimestamp);
            }

            switch (data.State)
            {
            case NotificationState.Successful:
                return(NotifyStatus.Successful);

            case NotificationState.WaitingForRetry:
                return(NotifyStatus.Scheduled);

            default:
                return(NotifyStatus.Failed);
            }
        }
 public static string UserId(this INotificationData notificationData) => notificationData.TopicName.Split(".")[2].Substring(0, 5);
Beispiel #10
0
 /// <summary>
 /// Populate notifiation with INotificationData data
 /// </summary>
 /// <param name="notificationData"></param>
 public abstract void PopulateNotificationValues(INotificationData notificationData);
 /// <summary>
 /// Initializes a new instance of the <see cref="NotificationController"/> class.
 /// </summary>
 /// <param name="logger">The logger service.</param>
 /// <param name="notificationDataService">The notification data service.</param>
 public NotificationController(ILogger logger, INotificationData notificationDataService, ISmtpService smtpService)
 {
     _logger = logger;
     _notificationDataService = notificationDataService;
     _smtpService             = smtpService;
 }
        public async Task ScheduleAndExecuteAsync_When_NotificationCreated_NotificationSent_Then_SuccessfulReturned(bool isErrorsCollectionNull)
        {
            // Arrange
            var mock      = new MockNotificationService();
            var recipient = new Recipient();
            var content   = new NotificationContent();

            var resolverResult = new ResolverResult()
            {
                ToAddress = "*****@*****.**"
            };

            var expectedAddedNotifications = new INotificationData[]
            {
                new MockNotificationData()
                {
                    TransportType = mock.MockNotificationTransporter.Object.TransporterType
                }
            };

            mock.SetupTransporters();
            mock.MockNotificationRecipientResolver.Setup(x => x.ResolveAsync(recipient, content, mock.MockNotificationTransporter.Object.TransporterType))
            .Returns(Task.FromResult <object>(resolverResult));


            mock.MockNotificationRepository.Setup(x => x.AddAsync(It.Is <IEnumerable <CreatableNotification> >((creatables) => creatables.Count() == 1 &&
                                                                                                               creatables.FirstOrDefault(item => item.TransportType == mock.MockNotificationTransporter.Object.TransporterType &&
                                                                                                                                         item.Recipients == resolverResult &&
                                                                                                                                         item.NotificationType == content.NotificationType &&
                                                                                                                                         item.Content == content) != null)))
            .Returns(Task.FromResult <IEnumerable <INotificationData> >(expectedAddedNotifications));

            mock.MockNotificationTransporter.Setup(x => x.SendAsync(expectedAddedNotifications[0].NotificationType,
                                                                    expectedAddedNotifications[0].Recipients,
                                                                    expectedAddedNotifications[0].Content))
            .Returns(Task.FromResult <IEnumerable <string> >(isErrorsCollectionNull ? null : new string[0]));

            // Act
            var result = await mock.Service.ScheduleAndExecuteAsync(content, recipient);

            // Assert
            Assert.Equal(NotifyStatus.Successful, result);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(expectedAddedNotifications[0].Id,
                                                                      NotificationState.Processing,
                                                                      0,
                                                                      null,
                                                                      null),
                                                   Times.Once);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(expectedAddedNotifications[0].Id,
                                                                      NotificationState.Successful,
                                                                      0,
                                                                      null,
                                                                      null),
                                                   Times.Once);


            mock.MockNotificationTransporter.Verify(x => x.SendAsync(expectedAddedNotifications[0].NotificationType,
                                                                     expectedAddedNotifications[0].Recipients,
                                                                     expectedAddedNotifications[0].Content),
                                                    Times.Once);
        }
        public async Task ScheduleAndExecuteAsync_When_NotificationCreated_NotificationNotSent_Then_ScheduledReturned()
        {
            // Arrange
            var mock      = new MockNotificationService();
            var recipient = new Recipient();
            var content   = new NotificationContent();

            var resolverResult = new ResolverResult()
            {
                ToAddress = "*****@*****.**"
            };

            var expectedAddedNotifications = new INotificationData[]
            {
                new MockNotificationData()
                {
                    TransportType = mock.MockNotificationTransporter.Object.TransporterType
                }
            };

            mock.SetupTransporters();
            mock.MockNotificationRecipientResolver.Setup(x => x.ResolveAsync(recipient, content, mock.MockNotificationTransporter.Object.TransporterType))
            .Returns(Task.FromResult <object>(resolverResult));


            mock.MockNotificationRepository.Setup(x => x.AddAsync(It.Is <IEnumerable <CreatableNotification> >((creatables) => creatables.Count() == 1 &&
                                                                                                               creatables.FirstOrDefault(item => item.TransportType == mock.MockNotificationTransporter.Object.TransporterType &&
                                                                                                                                         item.Recipients == resolverResult &&
                                                                                                                                         item.NotificationType == content.NotificationType &&
                                                                                                                                         item.Content == content) != null)))
            .Returns(Task.FromResult <IEnumerable <INotificationData> >(expectedAddedNotifications));

            var expectedNextSchedule = DateTime.UtcNow.AddSeconds(60);

            mock.MockNotificationTransporter.Setup(x => x.SendAsync(expectedAddedNotifications[0].NotificationType,
                                                                    expectedAddedNotifications[0].Recipients,
                                                                    expectedAddedNotifications[0].Content))
            .Callback(() => throw new SystemException());

            // Act
            var result = await mock.Service.ScheduleAndExecuteAsync(content, recipient);

            // Assert
            Assert.Equal(NotifyStatus.Scheduled, result);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(expectedAddedNotifications[0].Id,
                                                                      NotificationState.Processing,
                                                                      0,
                                                                      null,
                                                                      null),
                                                   Times.Once);

            mock.MockNotificationRepository.Verify(x => x.UpdateAsync(expectedAddedNotifications[0].Id,
                                                                      NotificationState.WaitingForRetry,
                                                                      1,
                                                                      It.IsAny <string>(),
                                                                      It.Is <DateTime>((value) => value >= expectedNextSchedule)),
                                                   Times.Once);


            mock.MockNotificationTransporter.Verify(x => x.SendAsync(expectedAddedNotifications[0].NotificationType,
                                                                     expectedAddedNotifications[0].Recipients,
                                                                     expectedAddedNotifications[0].Content),
                                                    Times.Once);
        }
Beispiel #14
0
 /// <summary>
 /// Shows notification to player
 /// </summary>
 /// <param name="value"></param>
 public override void ShowNotification(INotificationData value)
 {
     StartCoroutine(NotificationFlow(value));
 }
Beispiel #15
0
 /// <summary>
 /// Populate notifiation with INotificationData data
 /// </summary>
 /// <param name="achievement"></param>
 public override void PopulateNotificationValues(INotificationData achievement)
 {
     nameLabel.text = achievement.Name;
     icon.sprite    = achievement.Icon;
 }
Beispiel #16
0
 public abstract IEnumerator NotificationFlow(INotificationData value);
Beispiel #17
0
 public abstract void ShowNotification(INotificationData value);
Beispiel #18
0
        /// <summary>
        /// Called when observable notifies observers
        /// </summary>
        /// <param name="value"></param>
        public void OnNext(Achievement value)
        {
            INotificationData notification = (INotificationData)value;

            OnAchieve?.Invoke(notification);
        }