public void Edit_UserIsNotAuthorOfTheComment_ThrowsEditingCommentIsForbiddenException()
        {
            // Arrange
            int userId = 1;
            string newCommentText = "new_comment's_text";
            Comment comment = new Comment { CommentId = 2, UserId = userId + 1 };

            Expression<Func<Comment, object>>[] propertiesToInclude = { c => c.CommentEdit };

            // Arrange - mock commentRepository
            Mock<ICommentRepository> commentRepositoryMock = new Mock<ICommentRepository>();

            commentRepositoryMock.Setup(
            r =>
            r.GetById(comment.CommentId,
            It.Is<Expression<Func<Comment, object>>[]>(
            selector => ExpressionHelper.AreExpressionArraysEqual(selector, propertiesToInclude))))
            .Returns(comment);

            // Arrange - mock unitOfWork
            Mock<IUnitOfWork> unitOfWorkMock = new Mock<IUnitOfWork>();

            unitOfWorkMock.SetupGet(u => u.CommentRepository)
            .Returns(commentRepositoryMock.Object);

            // Arrange - create target
            ICommentService target = new CommentService(unitOfWorkMock.Object, this._commentValidationMock.Object,
            this._serviceSettings);

            // Act and Assert
            Assert.Throws<EditingCommentIsForbiddenException>(() => target.Edit(comment.CommentId, userId, newCommentText));

            commentRepositoryMock.Verify(
            r =>
            r.GetById(comment.CommentId,
            It.Is<Expression<Func<Comment, object>>[]>(
            selector => ExpressionHelper.AreExpressionArraysEqual(selector, propertiesToInclude))), Times.Once);

            commentRepositoryMock.Verify(r => r.Update(It.Is<Comment>(c => c.CommentId == comment.CommentId)), Times.Never);

            unitOfWorkMock.Verify(r => r.Save(), Times.Never);
        }
        public void Edit_UserIdIsLessOrEqualToZero_ThrowsArgumentOutOfRangeException()
        {
            // Arrange
            int commentId = 1;
            string newCommentText = "new_comment's_text";

            ICommentService target = new CommentService(new Mock<IUnitOfWork>().Object, this._commentValidationMock.Object,
            this._serviceSettings);

            // Act and Assert
            Assert.Throws<ArgumentOutOfRangeException>(() => target.Edit(commentId, -1, newCommentText));
            Assert.Throws<ArgumentOutOfRangeException>(() => target.Edit(commentId, 0, newCommentText));
        }
        public void Edit_NewCommentTextIsNull_ThrowsArgumentNullException()
        {
            // Arrange
            int commentId = 1;
            int userId = 2;

            ICommentService target = new CommentService(new Mock<IUnitOfWork>().Object, this._commentValidationMock.Object,
            this._serviceSettings);

            // Act and Assert
            Assert.Throws<ArgumentNullException>(() => target.Edit(commentId, userId, null));
        }
        public void Edit_PermittedPeriodForEditingExpired_ThrowsPermittedPeriodForEditingExpiredException()
        {
            // Arrange
            string newCommentText = "new_comment's_text";
            Comment comment = new Comment
            {
                CommentId = 1, UserId = 2,
                Date = DateTime.Now.AddSeconds(-(this._serviceSettings.PermittedPeriodForEditing + 1))
            };

            Expression<Func<Comment, object>>[] propertiesToInclude = { c => c.CommentEdit };

            // Arrange - mock commentRepository
            Mock<ICommentRepository> commentRepositoryMock = new Mock<ICommentRepository>();

            commentRepositoryMock.Setup(
            r =>
            r.GetById(comment.CommentId,
            It.Is<Expression<Func<Comment, object>>[]>(
            selector => ExpressionHelper.AreExpressionArraysEqual(selector, propertiesToInclude))))
            .Returns(comment);

            // Arrange - mock unitOfWork
            Mock<IUnitOfWork> unitOfWorkMock = new Mock<IUnitOfWork>();

            unitOfWorkMock.SetupGet(u => u.CommentRepository)
            .Returns(commentRepositoryMock.Object);

            // Arrange - create target
            ICommentService target = new CommentService(unitOfWorkMock.Object, this._commentValidationMock.Object,
            this._serviceSettings);

            // Act and Assert
            Assert.Throws<PermittedPeriodForEditingExpiredException>(
            () => target.Edit(comment.CommentId, comment.UserId, newCommentText));

            commentRepositoryMock.Verify(
            r =>
            r.GetById(comment.CommentId,
            It.Is<Expression<Func<Comment, object>>[]>(
            selector => ExpressionHelper.AreExpressionArraysEqual(selector, propertiesToInclude))), Times.Once);

            commentRepositoryMock.Verify(r => r.Update(It.Is<Comment>(c => c.CommentId == comment.CommentId)), Times.Never);

            unitOfWorkMock.Verify(r => r.Save(), Times.Never);
        }
        public void Edit_CommentHasNotBeenEditedYet_EditsTheComment()
        {
            // Arrange
            string newCommentText = "new_comment_text";
            string newValidatedCommentText = "new_validated_comment_text";
            Comment comment = new Comment { CommentId = 1, UserId = 2, Date = DateTime.Now };

            Expression<Func<Comment, object>>[] propertiesToInclude = { c => c.CommentEdit };

            // Arrange - mock commentRepository
            Mock<ICommentRepository> commentRepositoryMock = new Mock<ICommentRepository>();

            commentRepositoryMock.Setup(
            r =>
            r.GetById(comment.CommentId,
            It.Is<Expression<Func<Comment, object>>[]>(
            selector => ExpressionHelper.AreExpressionArraysEqual(selector, propertiesToInclude))))
            .Returns(comment);

            CommentEdit commentEdit = null;

            commentRepositoryMock.Setup(r => r.Update(It.IsAny<Comment>()))
            .Callback((Comment c) => commentEdit = c.CommentEdit);

            // Arrange - mock unitOfWork
            Mock<IUnitOfWork> unitOfWorkMock = new Mock<IUnitOfWork>();

            unitOfWorkMock.SetupGet(u => u.CommentRepository)
            .Returns(commentRepositoryMock.Object);

            // Arrange - mock commentValidation
            this._commentValidationMock.Setup(v => v.ValidateCommentText(newCommentText))
            .Returns(newValidatedCommentText);

            // Arrange - create target
            ICommentService target = new CommentService(unitOfWorkMock.Object, this._commentValidationMock.Object,
            this._serviceSettings);

            // Act
            target.Edit(comment.CommentId, comment.UserId, newCommentText);

            // Assert
            Assert.IsNotNull(commentEdit);
            Assert.IsTrue(new DateTime() != commentEdit.EditDate);

            commentRepositoryMock.Verify(
            r =>
            r.GetById(comment.CommentId,
            It.Is<Expression<Func<Comment, object>>[]>(
            selector => ExpressionHelper.AreExpressionArraysEqual(selector, propertiesToInclude))), Times.Once);

            commentRepositoryMock.Verify(
            r => r.Update(It.Is<Comment>(c => c.CommentId == comment.CommentId && c.Text == newValidatedCommentText)),
            Times.Once);

            unitOfWorkMock.Verify(r => r.Save(), Times.Once);

            this._commentValidationMock.Verify(v => v.ValidateCommentText(newCommentText), Times.Once);
        }