Esempio n. 1
0
        public void AddTodo_SendsNotification()
        {
            // explain data. this test may fail if we ran the AddTodo_ItemIs11thItemForToday_ExceptionThrown test
            var now               = DateTime.Now;
            var unique            = Guid.NewGuid();
            var builder           = new DbContextOptionsBuilder <DataContext>().UseSqlServer("Server=.;Database=SimpleTodo;Trusted_Connection=True;MultipleActiveResultSets=true");
            var mockNotifyService = new MockNotificationService();

            // explain this deletion
            using (var context = new DataContext(builder.Options))
            {
                context.TodoItems.RemoveRange(context.TodoItems);
                context.SaveChanges();
            }
            // arrange
            using (var context = new DataContext(builder.Options))
            {
                var service = new TodoService(context, mockNotifyService);
                service.AddTodo(new TodoDto
                {
                    Title   = "AddTodo_SendsNotification_" + unique,
                    DueDate = DateTime.Now.AddDays(1),
                });
            }

            // assert
            Assert.IsTrue(mockNotifyService.NotifyAddTodoItem_CalledOnce);
        }
        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);
        }
        public async Task ScheduleAndExecuteAsync_When_RecipientIsNull_Then_ArgumentNullExceptionThrown()
        {
            // Arrange
            var mock    = new MockNotificationService();
            var content = new NotificationContent();

            // Act & Assert
            await Assert.ThrowsAsync <ArgumentNullException>(() => mock.Service.ScheduleAndExecuteAsync(content, null));
        }
        public async Task ScheduleAsync_When_ContextIsNull_Then_ArgumentNullExceptionThrown()
        {
            // Arrange
            var mock      = new MockNotificationService();
            var recipient = new Recipient();

            // Act & Assert
            await Assert.ThrowsAsync <ArgumentNullException>(() => mock.Service.ScheduleAsync(null, recipient));
        }
        public async Task ScheduleAsync_When_TransporterPresent_TranspoterResolverIsNull_Then_InvalidOpertationExceptionThrown()
        {
            // Arrange
            var mock      = new MockNotificationService();
            var recipient = new Recipient();
            var content   = new NotificationContent();

            mock.SetupTransporters();
            mock.MockNotificationTransporter.Setup(x => x.RecipientResolver).Returns <INotificationRecipientResolver <Recipient> >(null);

            // Act & Assert
            await Assert.ThrowsAsync <InvalidOperationException>(() => mock.Service.ScheduleAsync(content, recipient));
        }
        public async Task ScheduleAndExecuteAsync_When_NotificationNotCreated_Then_SuccessfulReturned()
        {
            // Arrange
            var mock      = new MockNotificationService();
            var recipient = new Recipient();
            var content   = new NotificationContent();

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

            // Assert
            Assert.Equal(NotifyStatus.Successful, result);
        }
        public async Task ScheduleAsync_When_NoTransportersRegistered_Then_EmptyArray()
        {
            // Arrange
            var mock      = new MockNotificationService();
            var recipient = new Recipient();
            var content   = new NotificationContent();

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

            // Assert
            Assert.Empty(result);
        }
        public async Task ExecuteAsync_When_NoNotificationsPresent_Then_ZeroReturned()
        {
            // Arrange
            var mock = new MockNotificationService();

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

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

            // Assert
            Assert.Equal(0, result);
        }
        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);
        }
        public async Task ScheduleAsync_When_TransporterPresent_RecipientResolverReturnsNull_Then_EmptyArray()
        {
            // Arrange
            var mock      = new MockNotificationService();
            var recipient = new Recipient();
            var content   = new NotificationContent();

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

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

            // Assert
            Assert.Empty(result);

            mock.MockNotificationRecipientResolver.Verify(x => x.ResolveAsync(recipient, content, mock.MockNotificationTransporter.Object.TransporterType), Times.Once);
        }
        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);
        }
        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);
        }