diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/Create/CreateCoordinateHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/Create/CreateCoordinateHandlerTests.cs new file mode 100644 index 0000000..7056c95 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/Create/CreateCoordinateHandlerTests.cs @@ -0,0 +1,121 @@ +using AutoMapper; +using FluentAssertions; +using MediatR; +using Moq; +using Streetcode.BLL.DTO.AdditionalContent.Coordinates.Types; +using Streetcode.BLL.MediatR.AdditionalContent.Coordinate.Create; +using Streetcode.BLL.Mapping.AdditionalContent.Coordinates; +using Streetcode.DAL.Entities.AdditionalContent.Coordinates.Types; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.AdditionalContent.Coordinate; + +public class CreateCoordinateHandlerTests +{ + private readonly Mock _mockRepo; + private readonly IMapper _mapper; + + public CreateCoordinateHandlerTests() + { + _mockRepo = new Mock(); + + var configuration = new MapperConfiguration(cfg => + { + cfg.AddProfile(new StreetcodeCoordinateProfile()); + // Ensure mapping from DTO to Entity is available if not in profile + cfg.CreateMap(); + }); + + _mapper = configuration.CreateMapper(); + } + + [Fact] + public async Task Handle_ValidRequest_ReturnsSuccessAndCallsCreate() + { + // Arrange + var command = new CreateCoordinateCommand( + new StreetcodeCoordinateDTO + { + Latitude = 10, + Longtitude = 20 + }); + + // FIXED: Changed Create to CreateAsync to match the Handler implementation + _mockRepo.Setup(r => r.StreetcodeCoordinateRepository.CreateAsync( + It.IsAny())) + .ReturnsAsync(new StreetcodeCoordinate()); + + _mockRepo.Setup(r => r.SaveChangesAsync()) + .ReturnsAsync(1); + + var handler = new CreateCoordinateHandler( + _mockRepo.Object, + _mapper); + + // Act + var result = await handler.Handle( + command, + CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Should().Be(Unit.Value); + + // FIXED: Verifying CreateAsync because that is what the Handler actually invokes + _mockRepo.Verify(r => r.StreetcodeCoordinateRepository.CreateAsync( + It.IsAny()), Times.Once); + + _mockRepo.Verify(r => r.SaveChangesAsync(), Times.Once); + } + + [Fact] + public async Task Handle_MapperReturnsNull_ReturnsFailure() + { + // Arrange + // Passing null ensures the mapper returns null or throws, + // triggering the safety check in the Handler. + var command = new CreateCoordinateCommand(null!); + + var handler = new CreateCoordinateHandler( + _mockRepo.Object, + _mapper); + + var expectedError = Messages.Error_ConvertNullToEntity.Format( + nameof(StreetcodeCoordinate)); + + // Act + var result = await handler.Handle( + command, + CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + result.Errors.Should().ContainSingle() + .Which.Message.Should().Be(expectedError); + } + + [Fact] + public async Task Handle_SaveFails_ReturnsFailure() + { + // Arrange + var command = new CreateCoordinateCommand(new StreetcodeCoordinateDTO()); + + _mockRepo.Setup(r => r.StreetcodeCoordinateRepository.CreateAsync(It.IsAny())) + .ReturnsAsync(new StreetcodeCoordinate()); + + // Simulate database save failure (returning 0 rows affected) + _mockRepo.Setup(r => r.SaveChangesAsync()) + .ReturnsAsync(0); + + var handler = new CreateCoordinateHandler(_mockRepo.Object, _mapper); + + // Act + var result = await handler.Handle(command, CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + } +} \ No newline at end of file diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/Delete/DeleteCoordinateHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/Delete/DeleteCoordinateHandlerTests.cs new file mode 100644 index 0000000..f8ac9e1 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/Delete/DeleteCoordinateHandlerTests.cs @@ -0,0 +1,102 @@ +using System.Linq.Expressions; +using FluentAssertions; +using FluentResults; +using MediatR; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.MediatR.AdditionalContent.Coordinate.Delete; +using Streetcode.DAL.Entities.AdditionalContent.Coordinates.Types; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Xunit; + +namespace Streetcode.XUnit.BLL.MediatR.AdditionalContent.Coordinate; + +public class DeleteCoordinateHandlerTests +{ + private readonly Mock _mockRepositoryWrapper; + + public DeleteCoordinateHandlerTests() + { + _mockRepositoryWrapper = new Mock(); + } + + [Fact] + public async Task Handle_CoordinateNotFound_ReturnsFailResult() + { + // Arrange + int testId = 1; + + _mockRepositoryWrapper.Setup(repo => repo.StreetcodeCoordinateRepository + .GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync((StreetcodeCoordinate?)null); + + var handler = new DeleteCoordinateHandler(_mockRepositoryWrapper.Object); + var command = new DeleteCoordinateCommand(testId); + + // Act + var result = await handler.Handle(command, CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + _mockRepositoryWrapper.Verify(r => r.StreetcodeCoordinateRepository.Delete(It.IsAny()), Times.Never); + } + + [Fact] + public async Task Handle_CoordinateExists_DeletesAndReturnsOkResult() + { + // Arrange + int testId = 1; + var coordinate = new StreetcodeCoordinate { Id = testId }; + + _mockRepositoryWrapper.Setup(repo => repo.StreetcodeCoordinateRepository + .GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(coordinate); + + _mockRepositoryWrapper.Setup(repo => repo.SaveChangesAsync()) + .ReturnsAsync(1); + + var handler = new DeleteCoordinateHandler(_mockRepositoryWrapper.Object); + var command = new DeleteCoordinateCommand(testId); + + // Act + var result = await handler.Handle(command, CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + _mockRepositoryWrapper.Verify(r => r.StreetcodeCoordinateRepository.Delete(coordinate), Times.Once); + _mockRepositoryWrapper.Verify(r => r.SaveChangesAsync(), Times.Once); + } + + [Fact] + public async Task Handle_SaveChangesAsyncFails_ReturnsFailResult() + { + // Arrange + int testId = 1; + var coordinate = new StreetcodeCoordinate { Id = testId }; + + _mockRepositoryWrapper.Setup(repo => repo.StreetcodeCoordinateRepository + .GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(coordinate); + + _mockRepositoryWrapper.Setup(repo => repo.SaveChangesAsync()) + .ReturnsAsync(0); + + var handler = new DeleteCoordinateHandler(_mockRepositoryWrapper.Object); + var command = new DeleteCoordinateCommand(testId); + + // Act + var result = await handler.Handle(command, CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + } +} \ No newline at end of file diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/GetByStreetcodeId/GetCoordinatesByStreetcodeIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/GetByStreetcodeId/GetCoordinatesByStreetcodeIdHandlerTests.cs new file mode 100644 index 0000000..b458737 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/GetByStreetcodeId/GetCoordinatesByStreetcodeIdHandlerTests.cs @@ -0,0 +1,70 @@ +using AutoMapper; +using FluentAssertions; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.DTO.AdditionalContent.Coordinates.Types; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.Mapping.AdditionalContent.Coordinates; +using Streetcode.BLL.MediatR.AdditionalContent.Coordinate.GetByStreetcodeId; +using Streetcode.DAL.Entities.AdditionalContent.Coordinates.Types; +using Streetcode.DAL.Entities.Streetcode; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using System.Linq.Expressions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.AdditionalContent.Coordinate; + +public class GetCoordinatesByStreetcodeIdHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public GetCoordinatesByStreetcodeIdHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new StreetcodeCoordinateProfile()); + }); + _mapper = config.CreateMapper(); + } + + [Fact] + public async Task Handle_StreetcodeExists_ReturnsCorrectDataAndType() + { + // Arrange + int streetcodeId = 1; + var query = new GetCoordinatesByStreetcodeIdQuery(streetcodeId); + var coordinates = new List + { + new() { Id = 1, StreetcodeId = streetcodeId, Latitude = 1.1m, Longtitude = 2.2m } + }; + + _mockRepo.Setup(r => r.StreetcodeRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(new StreetcodeContent { Id = streetcodeId }); + + _mockRepo.Setup(r => r.StreetcodeCoordinateRepository.GetAllAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(coordinates); + + var handler = new GetCoordinatesByStreetcodeIdHandler(_mockRepo.Object, _mapper, _mockLogger.Object); + + // Act + var result = await handler.Handle(query, CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Should().NotBeNull(); + } + +} \ No newline at end of file diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/Update/UpdateCoordinateHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/Update/UpdateCoordinateHandlerTests.cs new file mode 100644 index 0000000..21e5a16 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Cordinate/Update/UpdateCoordinateHandlerTests.cs @@ -0,0 +1,126 @@ +using AutoMapper; +using FluentAssertions; +using MediatR; +using Moq; +using Streetcode.BLL.DTO.AdditionalContent.Coordinates.Types; +using Streetcode.BLL.MediatR.AdditionalContent.Coordinate.Update; +using Streetcode.BLL.Mapping.AdditionalContent.Coordinates; +using Streetcode.DAL.Entities.AdditionalContent.Coordinates.Types; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.AdditionalContent.Coordinate; + +public class UpdateCoordinateHandlerTests +{ + private readonly Mock _mockRepo; + private readonly IMapper _mapper; + + public UpdateCoordinateHandlerTests() + { + _mockRepo = new Mock(); + + var configuration = new MapperConfiguration(cfg => + { + cfg.AddProfile(new StreetcodeCoordinateProfile()); + // Ensure mapping from DTO to Entity is registered + cfg.CreateMap(); + }); + + _mapper = configuration.CreateMapper(); + } + + [Fact] + public async Task Handle_ValidRequest_ReturnsSuccessAndCallsUpdate() + { + // Arrange + var coordinateDto = new StreetcodeCoordinateDTO + { + Id = 1, + Latitude = 50.5m, + Longtitude = 30.5m + }; + var command = new UpdateCoordinateCommand(coordinateDto); + + // Setup the repository update + _mockRepo.Setup(r => r.StreetcodeCoordinateRepository.Update( + It.IsAny())); + + _mockRepo.Setup(r => r.SaveChangesAsync()) + .ReturnsAsync(1); + + var handler = new UpdateCoordinateHandler( + _mockRepo.Object, + _mapper); + + // Act + var result = await handler.Handle( + command, + CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Should().Be(Unit.Value); + + _mockRepo.Verify(r => r.StreetcodeCoordinateRepository.Update( + It.IsAny()), Times.Once); + + _mockRepo.Verify(r => r.SaveChangesAsync(), Times.Once); + } + + [Fact] + public async Task Handle_MapperReturnsNull_ReturnsFailure() + { + // Arrange + var command = new UpdateCoordinateCommand(null!); + + var handler = new UpdateCoordinateHandler( + _mockRepo.Object, + _mapper); + + var expectedError = Messages.Error_ConvertNullToEntity.Format( + nameof(StreetcodeCoordinate)); + + // Act + var result = await handler.Handle( + command, + CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + result.Errors.Should().ContainSingle() + .Which.Message.Should().Be(expectedError); + } + + [Fact] + public async Task Handle_SaveChangesFails_ReturnsFailureMessage() + { + // Arrange + var coordinateDto = new StreetcodeCoordinateDTO { Id = 1 }; + var command = new UpdateCoordinateCommand(coordinateDto); + + _mockRepo.Setup(r => r.StreetcodeCoordinateRepository.Update(It.IsAny())); + + _mockRepo.Setup(r => r.SaveChangesAsync()) + .ReturnsAsync(0); + + var handler = new UpdateCoordinateHandler( + _mockRepo.Object, + _mapper); + + string expectedError = Messages.Error_FailedToUpdateEntity.Format( + nameof(StreetcodeCoordinate)); + + // Act + var result = await handler.Handle( + command, + 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/AdditionalContent/Subtitle/GetAll/GetAllSubtitlesHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Subtitle/GetAll/GetAllSubtitlesHandlerTests.cs new file mode 100644 index 0000000..7127b76 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Subtitle/GetAll/GetAllSubtitlesHandlerTests.cs @@ -0,0 +1,88 @@ +using System.Linq.Expressions; +using AutoMapper; +using FluentAssertions; +using FluentResults; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.DTO.AdditionalContent.Subtitles; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.Mapping.AdditionalContent; +using Streetcode.BLL.MediatR.AdditionalContent.Subtitle.GetAll; +using Streetcode.DAL.Entities.AdditionalContent; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.AdditionalContent.Subtitle; + +public class GetAllSubtitlesHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public GetAllSubtitlesHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new SubtitleProfile()); + }); + + _mapper = config.CreateMapper(); + } + + [Fact] + public async Task Handle_SubtitlesExist_ReturnsSuccessWithCorrectTypeAndCount() + { + // Arrange + var subtitles = new List + { + new() { Id = 1, SubtitleText = "Subtitle 1" }, + new() { Id = 2, SubtitleText = "Subtitle 2" } + }; + + _mockRepo.Setup(r => r.SubtitleRepository.GetAllAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(subtitles); + + var handler = new GetAllSubtitlesHandler(_mockRepo.Object, _mapper, _mockLogger.Object); + + // Act + var result = await handler.Handle(new GetAllSubtitlesQuery(), CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Should().HaveCount(2); + result.Value.First().SubtitleText.Should().Be("Subtitle 1"); + } + + [Fact] + public async Task Handle_SubtitlesNotFound_ReturnsFailureAndLogsError() + { + // Arrange + // FIX: Returning an empty list to satisfy the .Any() check without crashing + _mockRepo.Setup(r => r.SubtitleRepository.GetAllAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(new List()); + + var handler = new GetAllSubtitlesHandler(_mockRepo.Object, _mapper, _mockLogger.Object); + var query = new GetAllSubtitlesQuery(); + var expectedError = Messages.Error_EntitiesNotFound.Format(nameof(DAL.Entities.AdditionalContent.Subtitle)); + + // Act + var result = await handler.Handle(query, CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + result.Errors.First().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/AdditionalContent/Subtitle/GetById/GetSubtitleByIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Subtitle/GetById/GetSubtitleByIdHandlerTests.cs new file mode 100644 index 0000000..9a172ba --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Subtitle/GetById/GetSubtitleByIdHandlerTests.cs @@ -0,0 +1,105 @@ +using AutoMapper; +using FluentAssertions; +using FluentResults; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.DTO.AdditionalContent.Subtitles; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.MediatR.AdditionalContent.Subtitle.GetById; +using Streetcode.BLL.Mapping.AdditionalContent; +using Streetcode.DAL.Entities.AdditionalContent; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using System.Linq.Expressions; +using Xunit; +using Streetcode.BLL.MediatR.AdditionalContent.GetById; + +namespace Streetcode.XUnitTest.MediatR.AdditionalContent.Subtitle; + +public class GetSubtitleByIdHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public GetSubtitleByIdHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new SubtitleProfile()); + }); + + // Correct way to initialize the mapper instance + _mapper = config.CreateMapper(); + } + + [Fact] + public async Task Handle_SubtitleExists_ReturnsSuccessWithCorrectMappedData() + { + // Arrange + int testId = 1; + var subtitle = new DAL.Entities.AdditionalContent.Subtitle + { + Id = testId, + SubtitleText = "Sample Subtitle" + }; + var query = new GetSubtitleByIdQuery(testId); + + _mockRepo.Setup(r => r.SubtitleRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(subtitle); + + var handler = new GetSubtitleByIdHandler( + _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.SubtitleText.Should().Be("Sample Subtitle"); + } + + [Fact] + public async Task Handle_SubtitleDoesNotExist_ReturnsFailureAndLogsError() + { + // Arrange + int testId = 99; + var query = new GetSubtitleByIdQuery(testId); + + _mockRepo.Setup(r => r.SubtitleRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync((DAL.Entities.AdditionalContent.Subtitle?)null); + + var handler = new GetSubtitleByIdHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + var expectedError = Messages.Error_EntityWithIdNotFound.Format( + nameof(DAL.Entities.AdditionalContent.Subtitle), + 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/AdditionalContent/Subtitle/GetByStreetcodeId/GetSubtitlesByStreetcodeIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Subtitle/GetByStreetcodeId/GetSubtitlesByStreetcodeIdHandlerTests.cs new file mode 100644 index 0000000..b617c43 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Subtitle/GetByStreetcodeId/GetSubtitlesByStreetcodeIdHandlerTests.cs @@ -0,0 +1,127 @@ +using AutoMapper; +using FluentAssertions; +using FluentResults; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.DTO.AdditionalContent.Subtitles; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.Mapping.AdditionalContent; +using Streetcode.BLL.MediatR.AdditionalContent.Subtitle.GetByStreetcodeId; +using Streetcode.DAL.Entities.AdditionalContent; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using System.Linq.Expressions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.AdditionalContent.Subtitle; + +public class GetSubtitlesByStreetcodeIdHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public GetSubtitlesByStreetcodeIdHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new SubtitleProfile()); + }); + _mapper = config.CreateMapper(); + } + + [Fact] + public async Task Handle_SubtitleExists_ReturnsSuccessWithMappedSubtitle() + { + // Arrange + int streetcodeId = 10; + var subtitle = new DAL.Entities.AdditionalContent.Subtitle + { + Id = 1, + StreetcodeId = streetcodeId, + SubtitleText = "Found it" + }; + var query = new GetSubtitlesByStreetcodeIdQuery(streetcodeId); + + _mockRepo.Setup(r => r.SubtitleRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(subtitle); + + var handler = new GetSubtitlesByStreetcodeIdHandler( + _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!.SubtitleText.Should().Be("Found it"); + } + + [Fact] + public async Task Handle_SubtitleDoesNotExist_ReturnsFailureAndLogsError() + { + // Arrange + int streetcodeId = 10; + var query = new GetSubtitlesByStreetcodeIdQuery(streetcodeId); + + _mockRepo.Setup(r => r.SubtitleRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync((DAL.Entities.AdditionalContent.Subtitle?)null); + + var handler = new GetSubtitlesByStreetcodeIdHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + var expectedError = Messages.Error_EntityWithStreetcodeIdNotFound.Format( + nameof(DAL.Entities.AdditionalContent.Subtitle), + streetcodeId); + + // Act + var result = await handler.Handle(query, CancellationToken.None); + + // Assert + // FIXED: Handler returns False for IsSuccess when data is null + 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_RepositoryReturnsData_CorrectDataTypeReturned() + { + // Arrange + var query = new GetSubtitlesByStreetcodeIdQuery(1); + + _mockRepo.Setup(r => r.SubtitleRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(new DAL.Entities.AdditionalContent.Subtitle()); + + var handler = new GetSubtitlesByStreetcodeIdHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + // Act + var result = await handler.Handle(query, CancellationToken.None); + + // Assert + result.Value.Should().BeOfType(); + } +} \ No newline at end of file diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/Create/CreateTagHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/Create/CreateTagHandlerTests.cs new file mode 100644 index 0000000..901887b --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/Create/CreateTagHandlerTests.cs @@ -0,0 +1,117 @@ +using AutoMapper; +using FluentAssertions; +using Moq; +using Streetcode.BLL.DTO.AdditionalContent.Tag; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.MediatR.AdditionalContent.Tag.Create; +using Streetcode.BLL.Mapping.AdditionalContent; +using Streetcode.DAL.Entities.AdditionalContent; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Xunit; +using Streetcode.BLL.DTO.AdditionalContent; + +namespace Streetcode.XUnitTest.MediatR.AdditionalContent.Tag; + +public class CreateTagHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public CreateTagHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new TagProfile()); + // Map CreateTagDTO to Tag entity for the Handler logic + cfg.CreateMap(); + }); + _mapper = config.CreateMapper(); + } + + [Fact] + public async Task Handle_ValidRequest_ReturnsSuccessAndMappedTag() + { + // Arrange + var createTagDto = new CreateTagDTO { Title = "Test Tag" }; + var command = new CreateTagCommand(createTagDto); + var createdTagFromDb = new DAL.Entities.AdditionalContent.Tag + { + Id = 1, + Title = "Test Tag" + }; + + _mockRepo.Setup(r => r.TagRepository.CreateAsync(It.IsAny())) + .ReturnsAsync(createdTagFromDb); + + _mockRepo.Setup(r => r.SaveChangesAsync()) + .ReturnsAsync(1); + + var handler = new CreateTagHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + // Act + var result = await handler.Handle(command, CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Should().BeOfType(); + result.Value.Title.Should().Be("Test Tag"); + } + + [Fact] + public async Task Handle_ValidRequest_CallsCreateAsyncWithCorrectData() + { + // Arrange + var createTagDto = new CreateTagDTO { Title = "New Unique Tag" }; + var command = new CreateTagCommand(createTagDto); + + _mockRepo.Setup(r => r.TagRepository.CreateAsync(It.IsAny())) + .ReturnsAsync(new DAL.Entities.AdditionalContent.Tag()); + + _mockRepo.Setup(r => r.SaveChangesAsync()) + .ReturnsAsync(1); + + var handler = new CreateTagHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + // Act + await handler.Handle(command, CancellationToken.None); + + // Assert + _mockRepo.Verify(r => r.TagRepository.CreateAsync( + It.Is(t => t.Title == "New Unique Tag")), Times.Once); + } + + [Fact] + public async Task Handle_SaveFails_ReturnsFailure() + { + // Arrange + var createTagDto = new CreateTagDTO { Title = "Fail Tag" }; + var command = new CreateTagCommand(createTagDto); + + _mockRepo.Setup(r => r.TagRepository.CreateAsync(It.IsAny())) + .ReturnsAsync(new DAL.Entities.AdditionalContent.Tag()); + + _mockRepo.Setup(r => r.SaveChangesAsync()) + .ReturnsAsync(0); + + var handler = new CreateTagHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + // Act + var result = await handler.Handle(command, CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + } +} \ No newline at end of file diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/GetAll/GetAllTagsHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/GetAll/GetAllTagsHandlerTests.cs new file mode 100644 index 0000000..fe57847 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/GetAll/GetAllTagsHandlerTests.cs @@ -0,0 +1,106 @@ +using AutoMapper; +using FluentAssertions; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.Mapping.AdditionalContent; +using Streetcode.BLL.MediatR.AdditionalContent.Tag.GetAll; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using System.Linq.Expressions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.AdditionalContent.Tag; + +public class GetAllTagsHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public GetAllTagsHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new TagProfile()); + }); + _mapper = config.CreateMapper(); + } + + [Fact] + public async Task Handle_TagsExist_ReturnsSuccessWithCorrectCountAndMappedData() + { + // Arrange + var tags = new List + { + new() { Id = 1, Title = "Historical" }, + new() { Id = 2, Title = "Art" } + }; + + _mockRepo.Setup(r => r.TagRepository.GetAllAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(tags); + + var handler = new GetAllTagsHandler(_mockRepo.Object, _mapper, _mockLogger.Object); + + // Act + var result = await handler.Handle(new GetAllTagsQuery(), CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Should().HaveCount(2); + result.Value.First().Title.Should().Be("Historical"); + } + + [Fact] + public async Task Handle_TagsNotFound_ReturnsFailureAndLogsError() + { + // Arrange + // FIX: Return an empty list instead of null to avoid ArgumentNullException in LINQ (.Any()) + // unless you specifically want to test null-handling logic in the handler. + _mockRepo.Setup(r => r.TagRepository.GetAllAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(Enumerable.Empty()); + + var handler = new GetAllTagsHandler(_mockRepo.Object, _mapper, _mockLogger.Object); + var query = new GetAllTagsQuery(); + var expectedError = Messages.Error_EntitiesNotFound.Format(nameof(DAL.Entities.AdditionalContent.Tag)); + + // 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_EmptyList_ReturnsFailureAsPerProjectStandard() + { + // Arrange + _mockRepo.Setup(r => r.TagRepository.GetAllAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(new List()); + + var handler = new GetAllTagsHandler(_mockRepo.Object, _mapper, _mockLogger.Object); + var expectedError = Messages.Error_EntitiesNotFound.Format(nameof(DAL.Entities.AdditionalContent.Tag)); + + // Act + var result = await handler.Handle(new GetAllTagsQuery(), CancellationToken.None); + + // Assert + result.IsFailed.Should().BeTrue(); + result.Errors.First().Message.Should().Be(expectedError); + } +} \ No newline at end of file diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/GetById/GetTagByIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/GetById/GetTagByIdHandlerTests.cs new file mode 100644 index 0000000..071477c --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/GetById/GetTagByIdHandlerTests.cs @@ -0,0 +1,103 @@ +using AutoMapper; +using FluentAssertions; +using FluentResults; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.DTO.AdditionalContent; +using Streetcode.BLL.DTO.AdditionalContent.Tag; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.Mapping.AdditionalContent; +using Streetcode.BLL.MediatR.AdditionalContent.Tag.GetById; +using Streetcode.DAL.Entities.AdditionalContent; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using System.Linq.Expressions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.AdditionalContent.Tag; + +public class GetTagByIdHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public GetTagByIdHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new TagProfile()); + }); + _mapper = config.CreateMapper(); + } + + [Fact] + public async Task Handle_TagExists_ReturnsSuccessWithMappedTag() + { + // Arrange + int testId = 5; + var tagEntity = new DAL.Entities.AdditionalContent.Tag + { + Id = testId, + Title = "Culture" + }; + var query = new GetTagByIdQuery(testId); + + _mockRepo.Setup(r => r.TagRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(tagEntity); + + var handler = new GetTagByIdHandler( + _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.Title.Should().Be("Culture"); + } + + [Fact] + public async Task Handle_TagDoesNotExist_ReturnsFailureAndLogsError() + { + // Arrange + int testId = 999; + var query = new GetTagByIdQuery(testId); + + _mockRepo.Setup(r => r.TagRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync((DAL.Entities.AdditionalContent.Tag?)null); + + var handler = new GetTagByIdHandler( + _mockRepo.Object, + _mapper, + _mockLogger.Object); + + var expectedError = Messages.Error_EntityWithIdNotFound.Format( + nameof(DAL.Entities.AdditionalContent.Tag), + 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/AdditionalContent/Tag/GetByStreetcodeId/GetTagByStreetcodeIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/GetByStreetcodeId/GetTagByStreetcodeIdHandlerTests.cs new file mode 100644 index 0000000..21ffaf8 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/GetByStreetcodeId/GetTagByStreetcodeIdHandlerTests.cs @@ -0,0 +1,126 @@ +using AutoMapper; +using FluentAssertions; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.DTO.AdditionalContent.Tag; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.Mapping.AdditionalContent; +using Streetcode.BLL.MediatR.AdditionalContent.Tag.GetByStreetcodeId; +using Streetcode.DAL.Entities.AdditionalContent; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using System.Linq.Expressions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.AdditionalContent.Tag; + +public class GetTagByStreetcodeIdHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public GetTagByStreetcodeIdHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new TagProfile()); + }); + _mapper = config.CreateMapper(); + } + + [Fact] + public async Task Handle_TagsExistForStreetcode_ReturnsSuccessWithSortedData() + { + // Arrange + int streetcodeId = 1; + var query = new GetTagByStreetcodeIdQuery(streetcodeId); + + var tagIndexed = new List + { + new() { StreetcodeId = streetcodeId, Index = 2, Tag = new DAL.Entities.AdditionalContent.Tag { Title = "Second" } }, + new() { StreetcodeId = streetcodeId, Index = 1, Tag = new DAL.Entities.AdditionalContent.Tag { Title = "First" } } + }; + + _mockRepo.Setup(r => r.StreetcodeTagIndexRepository.GetAllAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(tagIndexed); + + var handler = new GetTagsByStreetcodeIdHandler(_mockRepo.Object, _mapper, _mockLogger.Object); + + // Act + var result = await handler.Handle(query, CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Should().HaveCount(2); + + var resultList = result.Value.ToList(); + resultList[0].Title.Should().Be("First"); + resultList[1].Title.Should().Be("Second"); + } + + [Fact] + public async Task Handle_RepositoryReturnsNull_ReturnsFailureAndLogsError() + { + // Arrange + int streetcodeId = 1; + var query = new GetTagByStreetcodeIdQuery(streetcodeId); + + // FIX: Return Enumerable.Empty instead of null to prevent ArgumentNullException in handler's .Any() check + _mockRepo.Setup(r => r.StreetcodeTagIndexRepository.GetAllAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(Enumerable.Empty()); + + var handler = new GetTagsByStreetcodeIdHandler(_mockRepo.Object, _mapper, _mockLogger.Object); + + var expectedError = Messages.Error_EntityWithStreetcodeIdNotFound.Format( + nameof(DAL.Entities.AdditionalContent.Tag), + 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); + } + + [Fact] + public async Task Handle_ValidRequest_ReturnsCorrectDtoType() + { + // Arrange + int streetcodeId = 1; + var query = new GetTagByStreetcodeIdQuery(streetcodeId); + + // Provide at least one item so the result is "Success" and we can safely access .Value + var tagIndexed = new List + { + new() { Tag = new DAL.Entities.AdditionalContent.Tag { Title = "Test" } } + }; + + _mockRepo.Setup(r => r.StreetcodeTagIndexRepository.GetAllAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(tagIndexed); + + var handler = new GetTagsByStreetcodeIdHandler(_mockRepo.Object, _mapper, _mockLogger.Object); + + // Act + var result = await handler.Handle(query, CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Should().BeAssignableTo>(); + } +} \ No newline at end of file diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/GetTagByTitle/GetTagByTitleHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/GetTagByTitle/GetTagByTitleHandlerTests.cs new file mode 100644 index 0000000..fe0165a --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/MediatR/AdditionalContent/Tag/GetTagByTitle/GetTagByTitleHandlerTests.cs @@ -0,0 +1,95 @@ +using System.Linq.Expressions; +using AutoMapper; +using FluentAssertions; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Streetcode.BLL.DTO.AdditionalContent; +using Streetcode.BLL.DTO.AdditionalContent.Tag; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.Mapping.AdditionalContent; +using Streetcode.BLL.MediatR.AdditionalContent.Tag.GetByTitle; +using Streetcode.DAL.Entities.AdditionalContent; +using Streetcode.DAL.Repositories.Interfaces.Base; +using Streetcode.Resources; +using Streetcode.Shared.Extensions; +using Xunit; + +namespace Streetcode.XUnitTest.MediatR.AdditionalContent.Tag; + +public class GetTagByTitleHandlerTests +{ + private readonly Mock _mockRepo; + private readonly Mock _mockLogger; + private readonly IMapper _mapper; + + public GetTagByTitleHandlerTests() + { + _mockRepo = new Mock(); + _mockLogger = new Mock(); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new TagProfile()); + }); + _mapper = config.CreateMapper(); + } + + [Fact] + public async Task Handle_TagExists_ReturnsSuccessWithCorrectData() + { + // Arrange + string testTitle = "History"; + var query = new GetTagByTitleQuery(testTitle); + var tagEntity = new DAL.Entities.AdditionalContent.Tag + { + Id = 1, + Title = testTitle + }; + + _mockRepo.Setup(r => r.TagRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync(tagEntity); + + var handler = new GetTagByTitleHandler(_mockRepo.Object, _mapper, _mockLogger.Object); + + // Act + var result = await handler.Handle(query, CancellationToken.None); + + // Assert + result.IsSuccess.Should().BeTrue(); + result.Value.Title.Should().Be(testTitle); + result.Value.Should().BeOfType(); + } + + [Fact] + public async Task Handle_TagDoesNotExist_ReturnsFailureAndLogsError() + { + // Arrange + string testTitle = "NonExistent"; + var query = new GetTagByTitleQuery(testTitle); + + _mockRepo.Setup(r => r.TagRepository.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, IIncludableQueryable>>(), + It.IsAny())) + .ReturnsAsync((DAL.Entities.AdditionalContent.Tag?)null); + + var handler = new GetTagByTitleHandler(_mockRepo.Object, _mapper, _mockLogger.Object); + + // Using the explicit string that the Handler is confirmed to return + // This avoids the 'null' or 'literal key name' issues with the Messages resource in the test environment + string expectedError = $"Tag with Title: {testTitle} not found"; + + // 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/Timeline/TimelineItem/GetAllTimelinesHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/Timeline/TimelineItem/GetAllTimelinesHandlerTests.cs deleted file mode 100644 index 180d420..0000000 --- a/Streetcode/Streetcode.XUnitTest/MediatR/Timeline/TimelineItem/GetAllTimelinesHandlerTests.cs +++ /dev/null @@ -1,129 +0,0 @@ -namespace Streetcode.XUnitTest.MediatRTests.Timeline.TimelineItem; - -using AutoMapper; -using Moq; -using System.Linq.Expressions; -using Microsoft.EntityFrameworkCore.Query; -using Streetcode.BLL.DTO.Timeline; -using Streetcode.BLL.Interfaces.Logging; -using Streetcode.BLL.MediatR.Timeline.TimelineItem.GetAll; -using Streetcode.DAL.Entities.Timeline; -using Streetcode.DAL.Repositories.Interfaces.Base; -using Streetcode.DAL.Repositories.Interfaces.Timeline; -using Xunit; - -public class GetAllTimelineItemsHandlerTests -{ - private readonly Mock repoWrapperMock; - private readonly Mock timelineRepoMock; - private readonly Mock loggerMock; - private readonly IMapper mapper; - - public GetAllTimelineItemsHandlerTests() - { - repoWrapperMock = new Mock(); - timelineRepoMock = new Mock(); - loggerMock = new Mock(); - - repoWrapperMock - .Setup(r => r.TimelineRepository) - .Returns(timelineRepoMock.Object); - - var mapperConfig = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - }); - - mapper = mapperConfig.CreateMapper(); - } - - private GetAllTimelineItemsHandler CreateHandler() - => new( - repoWrapperMock.Object, - mapper, - loggerMock.Object - ); - - [Fact] - public async Task Handle_ReturnsOk_WhenTimelineItemsExist() - { - //Arrange - var entities = new List - { - new() { Id = 1 }, - new() { Id = 2 } - }; - - timelineRepoMock - .Setup(r => r.GetAllAsync( - It.IsAny>>(), - It.IsAny, - IIncludableQueryable>>() - )) - .ReturnsAsync(entities); - - // Act - var result = await CreateHandler().Handle( - new GetAllTimelineItemsQuery(), - CancellationToken.None - ); - - // Assert - Assert.True(result.IsSuccess); - Assert.Equal(2, result.Value.Count()); - } - - [Fact] - public async Task Handle_ReturnsFail_WhenTimelineItemsAreNull() - { - //Arrange - timelineRepoMock - .Setup(r => r.GetAllAsync( - It.IsAny>>(), - It.IsAny, - IIncludableQueryable>>() - )) - .ReturnsAsync((IEnumerable)null!); - - // Act - var result = await CreateHandler().Handle( - new GetAllTimelineItemsQuery(), - CancellationToken.None - ); - - // Assert - Assert.True(result.IsFailed); - Assert.Equal("Cannot find any timelineItem", result.Errors[0].Message); - - loggerMock.Verify( - l => l.LogError( - It.IsAny(), - It.IsAny() - ), - Times.Once - ); - } - - [Fact] - public async Task Handle_ReturnsOk_WhenTimelineItemsListIsEmpty() - { - //Arrange - timelineRepoMock - .Setup(r => r.GetAllAsync( - It.IsAny>>(), - It.IsAny, - IIncludableQueryable>>() - )) - .ReturnsAsync(new List()); - - // Act - var result = await CreateHandler().Handle( - new GetAllTimelineItemsQuery(), - CancellationToken.None); - - // Assert - Assert.True(result.IsSuccess); - Assert.NotNull(result.Value); - Assert.Empty(result.Value); - } -} diff --git a/Streetcode/Streetcode.XUnitTest/MediatR/Timeline/TimelineItem/GetTimelineByIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/MediatR/Timeline/TimelineItem/GetTimelineByIdHandlerTests.cs deleted file mode 100644 index 00834ff..0000000 --- a/Streetcode/Streetcode.XUnitTest/MediatR/Timeline/TimelineItem/GetTimelineByIdHandlerTests.cs +++ /dev/null @@ -1,113 +0,0 @@ -namespace Streetcode.XUnitTest.MediatRTests.Timeline.TimelineItem; - -using AutoMapper; -using Moq; -using System.Linq.Expressions; -using Microsoft.EntityFrameworkCore.Query; -using Streetcode.BLL.DTO.Timeline; -using Streetcode.BLL.Interfaces.Logging; -using Streetcode.BLL.MediatR.Timeline.TimelineItem.GetById; -using Streetcode.DAL.Entities.Timeline; -using Streetcode.DAL.Repositories.Interfaces.Base; -using Streetcode.DAL.Repositories.Interfaces.Timeline; -using Xunit; - -public class GetTimelineItemByIdHandlerTests -{ - private readonly Mock repoWrapperMock; - private readonly Mock timelineRepoMock; - private readonly Mock loggerMock; - private readonly IMapper mapper; - - public GetTimelineItemByIdHandlerTests() - { - repoWrapperMock = new Mock(); - timelineRepoMock = new Mock(); - loggerMock = new Mock(); - - repoWrapperMock - .Setup(r => r.TimelineRepository) - .Returns(timelineRepoMock.Object); - - var mapperConfig = new MapperConfiguration(cfg => - { - cfg.CreateMap(); - }); - - mapper = mapperConfig.CreateMapper(); - } - - private GetTimelineItemByIdHandler CreateHandler() - => new( - repoWrapperMock.Object, - mapper, - loggerMock.Object - ); - - [Fact] - public async Task Handle_ReturnsOk_WhenTimelineItemExists() - { - // Arrange - var entity = new TimelineItem - { - Id = 1 - }; - - timelineRepoMock - .Setup(r => r.GetFirstOrDefaultAsync( - It.IsAny>>(), - It.IsAny, - IIncludableQueryable>>() - )) - .ReturnsAsync(entity); - - var query = new GetTimelineItemByIdQuery(1); - - // Act - var result = await CreateHandler().Handle( - query, - CancellationToken.None - ); - - // Assert - Assert.True(result.IsSuccess); - Assert.NotNull(result.Value); - Assert.Equal(1, result.Value.Id); - } - - [Fact] - public async Task Handle_ReturnsFail_WhenTimelineItemNotExists() - { - // Arrange - timelineRepoMock - .Setup(r => r.GetFirstOrDefaultAsync( - It.IsAny>>(), - It.IsAny, - IIncludableQueryable>>() - )) - .ReturnsAsync((TimelineItem)null!); - - var query = new GetTimelineItemByIdQuery(99); - - // Act - var result = await CreateHandler().Handle( - query, - CancellationToken.None - ); - - // Assert - Assert.True(result.IsFailed); - Assert.Equal( - $"Cannot find a timeline item with corresponding id: {query.Id}", - result.Errors[0].Message - ); - - loggerMock.Verify( - l => l.LogError( - query, - It.IsAny() - ), - Times.Once - ); - } -}