public async Task BatchRecipients_AllConverstaionId_HasPendingInstallationShouldBeFalse()
        {
            // Arrange
            var    recipientService = this.GetRecipientsService();
            string notificationId   = "notificationId";
            var    recipients       = new List <SentNotificationDataEntity>()
            {
                new SentNotificationDataEntity()
                {
                    PartitionKey = notificationId, ConversationId = "conversationId"
                },
                new SentNotificationDataEntity()
                {
                    PartitionKey = notificationId, ConversationId = "conversationId2"
                },
            };

            this.sentNotificationRepository
            .Setup(x => x.BatchInsertOrMergeAsync(It.IsAny <IEnumerable <SentNotificationDataEntity> >()))
            .Returns(Task.CompletedTask);

            var recipientBatches = recipients.AsBatches(Constants.MaximumNumberOfRecipientsInBatch).ToList();

            // Act
            RecipientsInfo recipientsInfo = default;
            Func <Task>    task           = async() => recipientsInfo = await recipientService.BatchRecipients(recipients);

            // Assert
            await task.Should().NotThrowAsync();

            Assert.False(recipientsInfo.HasRecipientsPendingInstallation);
        }
        public async Task SyncRecipientsOrchestratorGetAllUsersTest()
        {
            // Arrange
            NotificationDataEntity notificationDataEntity = new NotificationDataEntity()
            {
                Id       = "notificationId",
                AllUsers = true,
            };
            var recipientsInfo = new RecipientsInfo(notificationDataEntity.Id)
            {
                HasRecipientsPendingInstallation = true,
            };

            recipientsInfo.BatchKeys.Add("batchKey");

            this.mockContext
            .Setup(x => x.GetInput <NotificationDataEntity>())
            .Returns(notificationDataEntity);
            this.mockContext
            .Setup(x => x.CallActivityWithRetryAsync(It.IsAny <string>(), It.IsAny <RetryOptions>(), It.IsAny <object>()))
            .Returns(Task.CompletedTask);
            this.mockContext
            .Setup(x => x.CallActivityWithRetryAsync <RecipientsInfo>(It.IsAny <string>(), It.IsAny <RetryOptions>(), It.IsAny <NotificationDataEntity>()))
            .ReturnsAsync(recipientsInfo);

            // Act
            Func <Task> task = async() => await SyncRecipientsOrchestrator.RunOrchestrator(this.mockContext.Object, this.mockLogger.Object);

            // Assert
            await task.Should().NotThrowAsync <ArgumentException>();

            this.mockContext.Verify(x => x.CallActivityWithRetryAsync <RecipientsInfo>(It.Is <string>(x => x.Equals(FunctionNames.SyncAllUsersActivity)), It.IsAny <RetryOptions>(), It.Is <NotificationDataEntity>(x => x.AllUsers)), Times.Once); // All Users flag is true
            this.mockContext.Verify(x => x.CallActivityWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.UpdateNotificationStatusActivity)), It.IsAny <RetryOptions>(), It.IsAny <object>()), Times.Once);
        }
예제 #3
0
        public async Task SyncTeamsActivitySuccessTest()
        {
            // Arrange
            var activityContext           = this.GetSyncTamActivity();
            IEnumerable <string> roasters = new List <string>()
            {
                "teamId1", "teamId2"
            };
            NotificationDataEntity notification = new NotificationDataEntity()
            {
                Id            = "notificationId",
                Rosters       = roasters,
                TeamsInString = "['teamId1','teamId2']",
            };

            IEnumerable <TeamDataEntity> teamData = new List <TeamDataEntity>()
            {
                new TeamDataEntity()
                {
                    TeamId = "teamId1"
                },
                new TeamDataEntity()
                {
                    TeamId = "teamId2"
                },
            };

            this.teamDataRepository
            .Setup(x => x.GetTeamDataEntitiesByIdsAsync(It.IsAny <IEnumerable <string> >()))
            .ReturnsAsync(teamData);
            this.notificationDataRepository
            .Setup(x => x.SaveWarningInNotificationDataEntityAsync(It.IsAny <string>(), It.IsAny <string>()))
            .Returns(Task.CompletedTask);
            this.sentNotificationDataRepository
            .Setup(x => x.BatchInsertOrMergeAsync(It.IsAny <IEnumerable <SentNotificationDataEntity> >()))
            .Returns(Task.CompletedTask);

            // Act
            RecipientsInfo recipientsInfo = default;
            Func <Task>    task           = async() =>
            {
                recipientsInfo = await activityContext.RunAsync(notification, this.log.Object);
            };

            // Assert
            await task.Should().NotThrowAsync();

            this.sentNotificationDataRepository.Verify(
                x => x.BatchInsertOrMergeAsync(It.Is <IEnumerable <SentNotificationDataEntity> >(
                                                   x => x.Count() == 2)), Times.Once);
            this.notificationDataRepository.Verify(x => x.SaveWarningInNotificationDataEntityAsync(It.Is <string>(x => x.Equals(notification.Id)), It.IsAny <string>()), Times.Never());
            this.recipientsService.Verify(x => x.BatchRecipients(It.IsAny <IEnumerable <SentNotificationDataEntity> >()), Times.Once);
        }
예제 #4
0
        public async Task PrepareToSendOrchestratorSuccessTest()
        {
            // Arrange
            Mock <NotificationDataEntity> mockNotificationDataEntity = new Mock <NotificationDataEntity>();
            NotificationDataEntity        notificationDataEntity     = new NotificationDataEntity()
            {
                Id = "123",
            };
            var recipientsInfo = new RecipientsInfo(notificationDataEntity.Id)
            {
                HasRecipientsPendingInstallation = true,
            };

            recipientsInfo.BatchKeys.Add("batchKey");

            this.mockContext
            .Setup(x => x.IsReplaying)
            .Returns(false);
            this.mockContext
            .Setup(x => x.GetInput <NotificationDataEntity>())
            .Returns(notificationDataEntity);

            this.mockContext
            .Setup(x => x.CallActivityWithRetryAsync(It.IsAny <string>(), It.IsAny <RetryOptions>(), notificationDataEntity))
            .Returns(Task.CompletedTask);
            this.mockContext
            .Setup(x => x.CallSubOrchestratorWithRetryAsync(It.IsAny <string>(), It.IsAny <RetryOptions>(), notificationDataEntity))
            .Returns(Task.CompletedTask);
            this.mockContext
            .Setup(x => x.CallSubOrchestratorWithRetryAsync <RecipientsInfo>(It.IsAny <string>(), It.IsAny <RetryOptions>(), notificationDataEntity))
            .ReturnsAsync(recipientsInfo);

            // Act
            Func <Task> task = async() => await PrepareToSendOrchestrator.RunOrchestrator(this.mockContext.Object, this.mockLogger.Object);

            // Assert
            await task.Should().NotThrowAsync <Exception>();

            this.mockContext.Verify(x => x.CallActivityWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.StoreMessageActivity)), It.IsAny <RetryOptions>(), It.IsAny <NotificationDataEntity>()), Times.Once());
            this.mockContext.Verify(x => x.CallActivityWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.UpdateNotificationStatusActivity)), It.IsAny <RetryOptions>(), It.IsAny <object>()), Times.Exactly(2));
            this.mockContext.Verify(x => x.CallActivityWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.DataAggregationTriggerActivity)), It.IsAny <RetryOptions>(), It.IsAny <object>()), Times.Once());
            this.mockContext.Verify(x => x.CallActivityWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.HandleFailureActivity)), It.IsAny <RetryOptions>(), It.IsAny <object>()), Times.Never);
            this.mockContext.Verify(x => x.CallSubOrchestratorWithRetryAsync <RecipientsInfo>(It.Is <string>(x => x.Equals(FunctionNames.SyncRecipientsOrchestrator)), It.IsAny <RetryOptions>(), It.IsAny <NotificationDataEntity>()), Times.Once());
            this.mockContext.Verify(x => x.CallSubOrchestratorWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.TeamsConversationOrchestrator)), It.IsAny <RetryOptions>(), It.IsAny <string>()), Times.Exactly(recipientsInfo.BatchKeys.Count));
            this.mockContext.Verify(x => x.CallSubOrchestratorWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.SendQueueOrchestrator)), It.IsAny <RetryOptions>(), It.IsAny <string>()), Times.Exactly(recipientsInfo.BatchKeys.Count));
        }
        public async Task BatchRecipients_NullParameter_ShouldThrowArgumentNullException()
        {
            // Arrange
            var recipientsInfo = new RecipientsInfo(this.notificationId);
            var activity       = this.RecipientsActivity();

            this.sentNotificationDataRepository.Setup(x => x.GetAllAsync(It.IsAny <string>(), null /*count*/))
            .ReturnsAsync(this.recipients);
            this.recipientsService.Setup(x => x.BatchRecipients(It.IsAny <IEnumerable <SentNotificationDataEntity> >()))
            .ReturnsAsync(recipientsInfo);

            // Act
            Func <Task> task = async() => await activity.BatchRecipientsAsync(null /*notification*/);

            // Assert
            await task.Should().ThrowAsync <ArgumentNullException>("notification is null");

            this.sentNotificationDataRepository.Verify(x => x.GetAllAsync(It.Is <string>(x => x.Equals(this.notificationId)), null /*count*/), Times.Never);
            this.recipientsService.Verify(x => x.BatchRecipients(It.IsAny <IEnumerable <SentNotificationDataEntity> >()), Times.Never);
        }
        public async Task BatchRecipients_AllParameters_ShouldBeSuccess()
        {
            // Arrange
            var recipientsInfo = new RecipientsInfo(this.notificationId);
            var activity       = this.RecipientsActivity();

            this.sentNotificationDataRepository.Setup(x => x.GetAllAsync(It.IsAny <string>(), null /*count*/))
            .ReturnsAsync(this.recipients);
            this.recipientsService.Setup(x => x.BatchRecipients(It.IsAny <IEnumerable <SentNotificationDataEntity> >()))
            .ReturnsAsync(recipientsInfo);

            // Act
            var result = await activity.BatchRecipientsAsync(this.notificationId);

            // Assert
            Assert.IsType <RecipientsInfo>(result);
            Assert.Equal(result.NotificationId, this.notificationId);
            this.sentNotificationDataRepository.Verify(x => x.GetAllAsync(It.Is <string>(x => x.Equals(this.notificationId)), null /*count*/), Times.Once);
            this.recipientsService.Verify(x => x.BatchRecipients(It.IsAny <IEnumerable <SentNotificationDataEntity> >()), Times.Once);
        }
예제 #7
0
        public async Task PrepareToSendOrchestration_ExceptionThrownFromInvokedActivity_ShouldInvokeHandleFailureActivity()
        {
            // Arrange
            Mock <NotificationDataEntity> mockNotificationDataEntity = new Mock <NotificationDataEntity>();
            NotificationDataEntity        notificationDataEntity     = new NotificationDataEntity()
            {
                Id = "123",
            };
            RecipientsInfo recipientsInfo = default;

            this.mockContext
            .Setup(x => x.IsReplaying)
            .Returns(false);
            this.mockContext
            .Setup(x => x.GetInput <NotificationDataEntity>())
            .Returns(notificationDataEntity);

            this.mockContext
            .Setup(x => x.CallActivityWithRetryAsync(It.IsAny <string>(), It.IsAny <RetryOptions>(), notificationDataEntity))
            .Throws(new Exception());
            this.mockContext
            .Setup(x => x.CallSubOrchestratorWithRetryAsync(It.IsAny <string>(), It.IsAny <RetryOptions>(), notificationDataEntity))
            .Returns(Task.CompletedTask);
            this.mockContext
            .Setup(x => x.CallSubOrchestratorWithRetryAsync <RecipientsInfo>(It.IsAny <string>(), It.IsAny <RetryOptions>(), notificationDataEntity))
            .ReturnsAsync(recipientsInfo);

            // Act
            Func <Task> task = async() => await PrepareToSendOrchestrator.RunOrchestrator(this.mockContext.Object, this.mockLogger.Object);

            // Assert
            await task.Should().NotThrowAsync <Exception>();

            this.mockContext.Verify(x => x.CallActivityWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.StoreMessageActivity)), It.IsAny <RetryOptions>(), It.IsAny <NotificationDataEntity>()), Times.Once());
            this.mockContext.Verify(x => x.CallActivityWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.UpdateNotificationStatusActivity)), It.IsAny <RetryOptions>(), It.IsAny <object>()), Times.Never);
            this.mockContext.Verify(x => x.CallActivityWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.DataAggregationTriggerActivity)), It.IsAny <RetryOptions>(), It.IsAny <object>()), Times.Never);
            this.mockContext.Verify(x => x.CallActivityWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.HandleFailureActivity)), It.IsAny <RetryOptions>(), It.IsAny <object>()), Times.Once);
            this.mockContext.Verify(x => x.CallSubOrchestratorWithRetryAsync <RecipientsInfo>(It.Is <string>(x => x.Equals(FunctionNames.SyncRecipientsOrchestrator)), It.IsAny <RetryOptions>(), It.IsAny <NotificationDataEntity>()), Times.Never);
            this.mockContext.Verify(x => x.CallSubOrchestratorWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.TeamsConversationOrchestrator)), It.IsAny <RetryOptions>(), It.IsAny <string>()), Times.Never);
            this.mockContext.Verify(x => x.CallSubOrchestratorWithRetryAsync(It.Is <string>(x => x.Equals(FunctionNames.SendQueueOrchestrator)), It.IsAny <RetryOptions>(), It.IsAny <string>()), Times.Never());
        }
        public async Task BatchRecipients_AllParameters_ShouldBeSuccess()
        {
            // Arrange
            var    recipientService = this.GetRecipientsService();
            string notificationId   = "notificationId";
            var    recipients       = new List <SentNotificationDataEntity>()
            {
                new SentNotificationDataEntity()
                {
                    PartitionKey = notificationId, ConversationId = "conversationId"
                },
                new SentNotificationDataEntity()
                {
                    PartitionKey = notificationId, ConversationId = string.Empty
                },
                new SentNotificationDataEntity()
                {
                    PartitionKey = notificationId, ConversationId = "conversationId2"
                },
            };

            this.sentNotificationRepository
            .Setup(x => x.BatchInsertOrMergeAsync(It.IsAny <IEnumerable <SentNotificationDataEntity> >()))
            .Returns(Task.CompletedTask);

            var recipientBatches = recipients.AsBatches(Constants.MaximumNumberOfRecipientsInBatch).ToList();

            // Act
            RecipientsInfo recipientsInfo = default;
            Func <Task>    task           = async() => recipientsInfo = await recipientService.BatchRecipients(recipients);

            // Assert
            await task.Should().NotThrowAsync();

            Assert.Equal(recipientsInfo.TotalRecipientCount, recipients.Count);
            Assert.True(recipientsInfo.HasRecipientsPendingInstallation);
            Assert.Equal(notificationId, PartitionKeyUtility.GetNotificationIdFromBatchPartitionKey(recipientsInfo.BatchKeys.First()));
            this.sentNotificationRepository.Verify(x => x.BatchInsertOrMergeAsync(It.IsAny <IEnumerable <SentNotificationDataEntity> >()), Times.Exactly(recipientBatches.Count));
        }
        private static async Task FanOutFanInSubOrchestratorAsync(IDurableOrchestrationContext context, string functionName, RecipientsInfo recipientsInfo)
        {
            var tasks = new List <Task>();

            // Fan-out
            foreach (var batchKey in recipientsInfo.BatchKeys)
            {
                var task = context.CallSubOrchestratorWithRetryAsync(
                    functionName,
                    FunctionSettings.DefaultRetryOptions,
                    batchKey);
                tasks.Add(task);
            }

            // Fan-in
            await Task.WhenAll(tasks);
        }