diff --git a/Streetcode/Streetcode.BLL/MediatR/Transactions/TransactionLink/GetAll/GetAllTransactLinksHandler.cs b/Streetcode/Streetcode.BLL/MediatR/Transactions/TransactionLink/GetAll/GetAllTransactLinksHandler.cs index 74e6002..17e8774 100644 --- a/Streetcode/Streetcode.BLL/MediatR/Transactions/TransactionLink/GetAll/GetAllTransactLinksHandler.cs +++ b/Streetcode/Streetcode.BLL/MediatR/Transactions/TransactionLink/GetAll/GetAllTransactLinksHandler.cs @@ -26,7 +26,7 @@ public async Task>> Handle(GetAllTransactLin { var transactLinks = await _repositoryWrapper.TransactLinksRepository.GetAllAsync(); - if (transactLinks.Any()) + if (transactLinks?.Any() ?? false) { return Result.Ok(_mapper.Map>(transactLinks)); } @@ -35,4 +35,4 @@ public async Task>> Handle(GetAllTransactLin _logger.LogError(request, errorMsg); return Result.Fail(new Error(errorMsg)); } -} +} \ No newline at end of file diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/Transactions/TransactionLink/GetAll/GetAllTransactLinksHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/Transactions/TransactionLink/GetAll/GetAllTransactLinksHandlerTests.cs new file mode 100644 index 0000000..7116930 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/Transactions/TransactionLink/GetAll/GetAllTransactLinksHandlerTests.cs @@ -0,0 +1,133 @@ +using System.Linq.Expressions; +using AutoMapper; +using FluentAssertions; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.DTO.Transactions; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.Mapping.Transactions; +using Streetcode.BLL.MediatR.Transactions.TransactionLink.GetAll; +using Streetcode.DAL.Entities.Transactions; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.Transactions.TransactionLink; + +public class GetAllTransactLinksHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public GetAllTransactLinksHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new TransactionLinkProfile()); + }); + _mapper = new Mapper(config); + } + + [Fact] + public async Task Handle_LinksExist_ReturnsSuccessWithMappedDTOs() + { + // Arrange + var links = new List + { + new() { Id = 1, Url = "https://streetcode.com/1", StreetcodeId = 1 }, + new() { Id = 2, Url = "https://streetcode.com/2", StreetcodeId = 2 } + }; + + _mockRepo.Setup(r => r.TransactLinksRepository.GetAllAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(links); + + var handler = new GetAllTransactLinksHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + // Act + var result = await handler.Handle( + new GetAllTransactLinksQuery(), + CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Should().HaveCount(2); + result.Value.First().Url.Should().Be("https://streetcode.com/1"); + } + + [Fact] + public async Task Handle_NoLinksFound_ReturnsFailureAndLogsError() + { + // Arrange + var query = new GetAllTransactLinksQuery(); + + _mockRepo.Setup(r => r.TransactLinksRepository.GetAllAsync( + (Expression>)null!, + (Func, IIncludableQueryable>)null!, + false)) + .ReturnsAsync(new List()); + + var handler = new GetAllTransactLinksHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + var expectedError = Messages.Error_EntitiesNotFound.Format( + nameof(Streetcode.DAL.Entities.Transactions.TransactionLink)); + + // Act + var result = await handler.Handle( + query, + CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + result.Errors.Should().ContainSingle() + .Which.Message.Should().Be(expectedError); + + _mockLogger.Verify(x => x.LogError( + query, + expectedError), Times.Once); + } + + [Fact] + public async Task Handle_RepositoryReturnsNull_ReturnsFailure() + { + // Arrange + _mockRepo.Setup(r => r.TransactLinksRepository.GetAllAsync( + null, + null, + false)) + .ReturnsAsync((IEnumerable?)null); + + var handler = new GetAllTransactLinksHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + var query = new GetAllTransactLinksQuery(); + + string expectedError = Messages.Error_EntitiesNotFound.Format( + nameof(Streetcode.DAL.Entities.Transactions.TransactionLink)); + + // Act + var result = await handler.Handle( + query, + CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + result.Errors.Should().ContainSingle() + .Which.Message.Should().Be(expectedError); + } +} \ No newline at end of file diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/Transactions/TransactionLink/GetById/GetTransactLinkByIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/Transactions/TransactionLink/GetById/GetTransactLinkByIdHandlerTests.cs new file mode 100644 index 0000000..285796a --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/Transactions/TransactionLink/GetById/GetTransactLinkByIdHandlerTests.cs @@ -0,0 +1,110 @@ +using System.Linq.Expressions; +using AutoMapper; +using FluentAssertions; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.DTO.Transactions; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.Mapping.Transactions; +using Streetcode.BLL.MediatR.Transactions.TransactionLink.GetById; +using Streetcode.DAL.Entities.Transactions; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.Transactions.TransactionLink; + +public class GetTransactLinkByIdHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public GetTransactLinkByIdHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new TransactionLinkProfile()); + }); + _mapper = new Mapper(config); + } + + [Fact] + public async Task Handle_LinkExists_ReturnsSuccessWithMappedDTO() + { + // Arrange + int testId = 1; + var link = new Streetcode.DAL.Entities.Transactions.TransactionLink + { + Id = testId, + Url = "https://streetcode.com/donate", + StreetcodeId = 10 + }; + var query = new GetTransactLinkByIdQuery( + testId); + + _mockRepo.Setup(r => r.TransactLinksRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(link); + + var handler = new GetTransactLinkByIdHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + // Act + var result = await handler.Handle( + query, + CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Should().BeOfType(); + result.Value.Id.Should().Be(testId); + result.Value.Url.Should().Be("https://streetcode.com/donate"); + } + + [Fact] + public async Task Handle_LinkDoesNotExist_ReturnsFailureAndLogsError() + { + // Arrange + int testId = 99; + var query = new GetTransactLinkByIdQuery( + testId); + + _mockRepo.Setup(r => r.TransactLinksRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + null, + false)) + .ReturnsAsync((Streetcode.DAL.Entities.Transactions.TransactionLink?)null); + + var handler = new GetTransactLinkByIdHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + var expectedError = Messages.Error_EntityWithIdNotFound.Format( + nameof(Streetcode.DAL.Entities.Transactions.TransactionLink), + testId); + + // Act + var result = await handler.Handle( + query, + CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + result.Errors.Should().ContainSingle() + .Which.Message.Should().Be(expectedError); + + _mockLogger.Verify(x => x.LogError( + query, + expectedError), Times.Once); + } +} \ No newline at end of file diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/Transactions/TransactionLink/GetByStreetcodeId/GetTransactLinkByStreetcodeIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/Transactions/TransactionLink/GetByStreetcodeId/GetTransactLinkByStreetcodeIdHandlerTests.cs new file mode 100644 index 0000000..991638e --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/Transactions/TransactionLink/GetByStreetcodeId/GetTransactLinkByStreetcodeIdHandlerTests.cs @@ -0,0 +1,109 @@ +using System.Linq.Expressions; +using AutoMapper; +using FluentAssertions; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.DTO.Transactions; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.Mapping.Transactions; +using Streetcode.BLL.MediatR.Transactions.TransactionLink.GetByStreetcodeId; +using Streetcode.DAL.Entities.Transactions; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.Transactions.TransactionLink; + +public class GetTransactLinkByStreetcodeIdHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public GetTransactLinkByStreetcodeIdHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new TransactionLinkProfile()); + }); + _mapper = new Mapper(config); + } + + [Fact] + public async Task Handle_LinkExists_ReturnsSuccessWithMappedDTO() + { + // Arrange + int streetcodeId = 5; + var link = new Streetcode.DAL.Entities.Transactions.TransactionLink + { + Id = 1, + StreetcodeId = streetcodeId, + Url = "https://streetcode.com/donate" + }; + var query = new GetTransactLinkByStreetcodeIdQuery( + streetcodeId); + + _mockRepo.Setup(r => r.TransactLinksRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(link); + + var handler = new GetTransactLinkByStreetcodeIdHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + // Act + var result = await handler.Handle( + query, + CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Should().NotBeNull(); + result.Value!.StreetcodeId.Should().Be(streetcodeId); + } + + [Fact] + public async Task Handle_LinkDoesNotExist_ReturnsFailureAndLogsError() + { + // Arrange + int streetcodeId = 10; + var query = new GetTransactLinkByStreetcodeIdQuery( + streetcodeId); + + _mockRepo.Setup(r => r.TransactLinksRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + null, + false)) + .ReturnsAsync((Streetcode.DAL.Entities.Transactions.TransactionLink?)null); + + var handler = new GetTransactLinkByStreetcodeIdHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + var expectedError = Messages.Error_EntityWithStreetcodeIdNotFound.Format( + nameof(Streetcode.DAL.Entities.Transactions.TransactionLink), + streetcodeId); + + // Act + var result = await handler.Handle( + query, + CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + result.Errors.Should().ContainSingle() + .Which.Message.Should().Be(expectedError); + + _mockLogger.Verify(x => x.LogError( + query, + expectedError), Times.Once); + } +} \ No newline at end of file