Skip to content

Commit

Permalink
Use small api toolkit base validation handler
Browse files Browse the repository at this point in the history
  • Loading branch information
Gramli committed Sep 10, 2024
1 parent 0d0b15b commit f66b34c
Show file tree
Hide file tree
Showing 30 changed files with 198 additions and 264 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using Microsoft.AspNetCore.Mvc.Testing;
using Newtonsoft.Json;
using SmallApiToolkit.Core.Response;
using System.Text;
using Weather.Domain.Commands;
using Weather.Domain.Dtos;
using Weather.Domain.Http;

namespace Weather.API.SystemTests
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Weather.Core.Abstractions;
using SmallApiToolkit.Core.RequestHandlers;
using SmallApiToolkit.Core.Validation;
using Weather.Core.Abstractions;
using Weather.Core.Commands;
using Weather.Core.Resources;
using Weather.Domain.Commands;
Expand All @@ -10,15 +12,15 @@ namespace Weather.Core.UnitTests.Commands
public class AddFavoriteHandlerTests
{
private readonly Mock<IWeatherCommandsRepository> _weatherCommandsRepositoryMock;
private readonly Mock<IValidator<AddFavoriteCommand>> _addFavoriteCommandValidatorMock;
private readonly Mock<ILogger<IAddFavoriteHandler>> _loggerMock;
private readonly Mock<IRequestValidator<AddFavoriteCommand>> _addFavoriteCommandValidatorMock;
private readonly Mock<ILogger<AddFavoriteHandler>> _loggerMock;

private readonly IAddFavoriteHandler _uut;
private readonly IHttpRequestHandler<int, AddFavoriteCommand> _uut;
public AddFavoriteHandlerTests()
{
_weatherCommandsRepositoryMock = new Mock<IWeatherCommandsRepository>();
_addFavoriteCommandValidatorMock = new Mock<IValidator<AddFavoriteCommand>>();
_loggerMock = new Mock<ILogger<IAddFavoriteHandler>>();
_weatherCommandsRepositoryMock = new();
_addFavoriteCommandValidatorMock = new();
_loggerMock = new();

_uut = new AddFavoriteHandler(_weatherCommandsRepositoryMock.Object, _addFavoriteCommandValidatorMock.Object, _loggerMock.Object);
}
Expand All @@ -30,15 +32,15 @@ public async Task InvalidLocation()
//Arrange
var addFavoriteCommand = new AddFavoriteCommand { Location = new Domain.Dtos.LocationDto { Latitude = 1, Longitude = 1 } };

_addFavoriteCommandValidatorMock.Setup(x => x.IsValid(It.IsAny<AddFavoriteCommand>())).Returns(false);
_addFavoriteCommandValidatorMock.Setup(x => x.Validate(It.IsAny<AddFavoriteCommand>())).Returns(new RequestValidationResult { IsValid = false});

//Act
var result = await _uut.HandleAsync(addFavoriteCommand, CancellationToken.None);

//Assert
Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode);
Assert.Single(result.Errors);
_addFavoriteCommandValidatorMock.Verify(x => x.IsValid(It.Is<AddFavoriteCommand>(y => y.Equals(addFavoriteCommand))), Times.Once);
_addFavoriteCommandValidatorMock.Verify(x => x.Validate(It.Is<AddFavoriteCommand>(y => y.Equals(addFavoriteCommand))), Times.Once);
}

[Fact]
Expand All @@ -48,7 +50,7 @@ public async Task AddFavoriteLocation_Failed()
var addFavoriteCommand = new AddFavoriteCommand { Location = new Domain.Dtos.LocationDto { Latitude = 1, Longitude = 1 } };
var errorMessage = "errorMessage";

_addFavoriteCommandValidatorMock.Setup(x => x.IsValid(It.IsAny<AddFavoriteCommand>())).Returns(true);
_addFavoriteCommandValidatorMock.Setup(x => x.Validate(It.IsAny<AddFavoriteCommand>())).Returns(new RequestValidationResult { IsValid = true });
_weatherCommandsRepositoryMock.Setup(x => x.AddFavoriteLocation(It.IsAny<AddFavoriteCommand>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Fail(errorMessage));

//Act
Expand All @@ -58,7 +60,7 @@ public async Task AddFavoriteLocation_Failed()
Assert.Equal(HttpStatusCode.InternalServerError, result.StatusCode);
Assert.Single(result.Errors);
Assert.Equal(ErrorMessages.CantStoreLocation, result.Errors.Single());
_addFavoriteCommandValidatorMock.Verify(x => x.IsValid(It.Is<AddFavoriteCommand>(y => y.Equals(addFavoriteCommand))), Times.Once);
_addFavoriteCommandValidatorMock.Verify(x => x.Validate(It.Is<AddFavoriteCommand>(y => y.Equals(addFavoriteCommand))), Times.Once);
_weatherCommandsRepositoryMock.Verify(x => x.AddFavoriteLocation(It.Is<AddFavoriteCommand>(y=>y.Equals(addFavoriteCommand)), It.IsAny<CancellationToken>()), Times.Once);
_loggerMock.VerifyLog(LogLevel.Error, LogEvents.FavoriteWeathersStoreToDatabase, errorMessage, Times.Once());
}
Expand All @@ -70,7 +72,7 @@ public async Task Success()
var addFavoriteCommand = new AddFavoriteCommand { Location = new Domain.Dtos.LocationDto { Latitude = 1, Longitude = 1 } };
var locationId = 1;

_addFavoriteCommandValidatorMock.Setup(x => x.IsValid(It.IsAny<AddFavoriteCommand>())).Returns(true);
_addFavoriteCommandValidatorMock.Setup(x => x.Validate(It.IsAny<AddFavoriteCommand>())).Returns(new RequestValidationResult { IsValid = true });
_weatherCommandsRepositoryMock.Setup(x => x.AddFavoriteLocation(It.IsAny<AddFavoriteCommand>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Ok(locationId));

//Act
Expand All @@ -80,7 +82,7 @@ public async Task Success()
Assert.Equal(HttpStatusCode.OK, result.StatusCode);
Assert.Empty(result.Errors);
Assert.Equal(locationId, result.Data);
_addFavoriteCommandValidatorMock.Verify(x => x.IsValid(It.Is<AddFavoriteCommand>(y => y.Equals(addFavoriteCommand))), Times.Once);
_addFavoriteCommandValidatorMock.Verify(x => x.Validate(It.Is<AddFavoriteCommand>(y => y.Equals(addFavoriteCommand))), Times.Once);
_weatherCommandsRepositoryMock.Verify(x => x.AddFavoriteLocation(It.Is<AddFavoriteCommand>(y => y.Equals(addFavoriteCommand)), It.IsAny<CancellationToken>()), Times.Once);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Weather.Core.Abstractions;
using SmallApiToolkit.Core.RequestHandlers;
using SmallApiToolkit.Core.Validation;
using Weather.Core.Abstractions;
using Weather.Core.Commands;
using Weather.Domain.Commands;

Expand All @@ -7,9 +9,9 @@ namespace Weather.Core.UnitTests.Commands
public class DeleteFavoriteHandlerTests
{
private readonly Mock<IWeatherCommandsRepository> _weatherCommandsRepositoryMock;
private readonly Mock<IValidator<DeleteFavoriteCommand>> _validatorMock;
private readonly Mock<IRequestValidator<DeleteFavoriteCommand>> _validatorMock;

private readonly IDeleteFavoriteHandler _uut;
private readonly IHttpRequestHandler<bool, DeleteFavoriteCommand> _uut;
public DeleteFavoriteHandlerTests()
{
_weatherCommandsRepositoryMock = new();
Expand All @@ -24,24 +26,24 @@ public async Task InvalidRequest()
//Arrange
var deleteFavoriteCommand = new DeleteFavoriteCommand { Id = 5 };

_validatorMock.Setup(x => x.IsValid(It.IsAny<DeleteFavoriteCommand>())).Returns(false);
_validatorMock.Setup(x => x.Validate(It.IsAny<DeleteFavoriteCommand>())).Returns(new RequestValidationResult { IsValid = false});

//Act
var result = await _uut.HandleAsync(deleteFavoriteCommand, CancellationToken.None);

//Assert
Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode);
Assert.Single(result.Errors);
_validatorMock.Verify(x => x.IsValid(It.Is<DeleteFavoriteCommand>(y => y.Equals(deleteFavoriteCommand))), Times.Once);
_validatorMock.Verify(x => x.Validate(It.Is<DeleteFavoriteCommand>(y => y.Equals(deleteFavoriteCommand))), Times.Once);
}

[Fact]
public async Task DeleteFavoriteLocationSafeAsync_Failed()
{
//Arrange
var deleteFavoriteCommand = new DeleteFavoriteCommand { Id = 5 };

_validatorMock.Setup(x => x.IsValid(deleteFavoriteCommand)).Returns(true);
_validatorMock.Setup(x => x.Validate(It.IsAny<DeleteFavoriteCommand>())).Returns(new RequestValidationResult { IsValid = true });
_weatherCommandsRepositoryMock.Setup(x => x.DeleteFavoriteLocationSafeAsync(deleteFavoriteCommand, CancellationToken.None))
.ReturnsAsync(Result.Fail(string.Empty));

Expand All @@ -51,7 +53,7 @@ public async Task DeleteFavoriteLocationSafeAsync_Failed()
//Assert
Assert.Equal(HttpStatusCode.InternalServerError, result.StatusCode);
Assert.Single(result.Errors);
_validatorMock.Verify(x => x.IsValid(deleteFavoriteCommand), Times.Once);
_validatorMock.Verify(x => x.Validate(deleteFavoriteCommand), Times.Once);
_weatherCommandsRepositoryMock.Verify(x => x.DeleteFavoriteLocationSafeAsync(deleteFavoriteCommand, CancellationToken.None), Times.Once);
}

Expand All @@ -61,7 +63,7 @@ public async Task DeleteFavoriteLocationSafeAsync_Success()
//Arrange
var deleteFavoriteCommand = new DeleteFavoriteCommand { Id = 5 };

_validatorMock.Setup(x => x.IsValid(deleteFavoriteCommand)).Returns(true);
_validatorMock.Setup(x => x.Validate(It.IsAny<DeleteFavoriteCommand>())).Returns(new RequestValidationResult { IsValid = true });
_weatherCommandsRepositoryMock.Setup(x => x.DeleteFavoriteLocationSafeAsync(deleteFavoriteCommand, CancellationToken.None))
.ReturnsAsync(Result.Ok());

Expand All @@ -71,7 +73,7 @@ public async Task DeleteFavoriteLocationSafeAsync_Success()
//Assert
Assert.Equal(HttpStatusCode.OK, result.StatusCode);
Assert.Empty(result.Errors);
_validatorMock.Verify(x => x.IsValid(deleteFavoriteCommand), Times.Once);
_validatorMock.Verify(x => x.Validate(deleteFavoriteCommand), Times.Once);
_weatherCommandsRepositoryMock.Verify(x => x.DeleteFavoriteLocationSafeAsync(deleteFavoriteCommand, CancellationToken.None), Times.Once);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Validot.Results;
using SmallApiToolkit.Core.RequestHandlers;
using SmallApiToolkit.Core.Validation;
using Validot.Results;
using Weather.Core.Abstractions;
using Weather.Core.Queries;
using Weather.Core.Resources;
Expand All @@ -11,18 +13,18 @@ namespace Weather.Core.UnitTests.Queries
{
public class GetCurrentWeatherHandlerTests
{
private readonly Mock<IValidator<GetCurrentWeatherQuery>> _getCurrentWeatherQueryValidatorMock;
private readonly Mock<IValidator<CurrentWeatherDto>> _currentWeatherValidatorMock;
private readonly Mock<IRequestValidator<GetCurrentWeatherQuery>> _getCurrentWeatherQueryValidatorMock;
private readonly Mock<IRequestValidator<CurrentWeatherDto>> _currentWeatherValidatorMock;
private readonly Mock<IWeatherService> _weatherServiceMock;
private readonly Mock<ILogger<IGetCurrentWeatherHandler>> _loggerMock;
private readonly Mock<ILogger<GetCurrentWeatherHandler>> _loggerMock;

private readonly IGetCurrentWeatherHandler _uut;
private readonly IHttpRequestHandler<CurrentWeatherDto, GetCurrentWeatherQuery> _uut;
public GetCurrentWeatherHandlerTests()
{
_getCurrentWeatherQueryValidatorMock = new Mock<IValidator<GetCurrentWeatherQuery>>();
_currentWeatherValidatorMock = new Mock<IValidator<CurrentWeatherDto>>();
_weatherServiceMock = new Mock<IWeatherService>();
_loggerMock = new Mock<ILogger<IGetCurrentWeatherHandler>>();
_getCurrentWeatherQueryValidatorMock = new();
_currentWeatherValidatorMock = new();
_weatherServiceMock = new();
_loggerMock = new();

_uut = new GetCurrentWeatherHandler(_getCurrentWeatherQueryValidatorMock.Object, _currentWeatherValidatorMock.Object, _weatherServiceMock.Object, _loggerMock.Object);
}
Expand All @@ -33,7 +35,7 @@ public async Task InvalidLocation()
//Arrange
var getCurrentWeatherQuery = new GetCurrentWeatherQuery(1,1);

_getCurrentWeatherQueryValidatorMock.Setup(x => x.IsValid(It.IsAny<GetCurrentWeatherQuery>())).Returns(false);
_getCurrentWeatherQueryValidatorMock.Setup(x => x.Validate(It.IsAny<GetCurrentWeatherQuery>())).Returns(new RequestValidationResult { IsValid = false});

//Act
var result = await _uut.HandleAsync(getCurrentWeatherQuery, CancellationToken.None);
Expand All @@ -42,7 +44,7 @@ public async Task InvalidLocation()
Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode);
Assert.Single(result.Errors);
Assert.Null(result.Data);
_getCurrentWeatherQueryValidatorMock.Verify(x => x.IsValid(It.Is<GetCurrentWeatherQuery>(y => y.Equals(getCurrentWeatherQuery))), Times.Once);
_getCurrentWeatherQueryValidatorMock.Verify(x => x.Validate(It.Is<GetCurrentWeatherQuery>(y => y.Equals(getCurrentWeatherQuery))), Times.Once);
}

[Fact]
Expand All @@ -52,7 +54,7 @@ public async Task GetCurrentWeather_Failed()
var errorMessage = "error";
var getCurrentWeatherQuery = new GetCurrentWeatherQuery(1, 1);

_getCurrentWeatherQueryValidatorMock.Setup(x => x.IsValid(It.IsAny<GetCurrentWeatherQuery>())).Returns(true);
_getCurrentWeatherQueryValidatorMock.Setup(x => x.Validate(It.IsAny<GetCurrentWeatherQuery>())).Returns(new RequestValidationResult { IsValid = true });
_weatherServiceMock.Setup(x=>x.GetCurrentWeather(It.IsAny<LocationDto>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Fail(errorMessage));
//Act
var result = await _uut.HandleAsync(getCurrentWeatherQuery, CancellationToken.None);
Expand All @@ -62,7 +64,7 @@ public async Task GetCurrentWeather_Failed()
Assert.Single(result.Errors);
Assert.Equal(ErrorMessages.ExternalApiError, result.Errors.Single());
Assert.Null(result.Data);
_getCurrentWeatherQueryValidatorMock.Verify(x => x.IsValid(It.Is<GetCurrentWeatherQuery>(y => y.Equals(getCurrentWeatherQuery))), Times.Once);
_getCurrentWeatherQueryValidatorMock.Verify(x => x.Validate(It.Is<GetCurrentWeatherQuery>(y => y.Equals(getCurrentWeatherQuery))), Times.Once);
_weatherServiceMock.Verify(x => x.GetCurrentWeather(It.Is<LocationDto>(y => y.Equals(getCurrentWeatherQuery.Location)), It.IsAny<CancellationToken>()), Times.Once);
_loggerMock.VerifyLog(LogLevel.Error, LogEvents.CurrentWeathersGet, errorMessage, Times.Once());
}
Expand All @@ -74,11 +76,9 @@ public async Task CurrentWeather_ValidationFailed()
var getCurrentWeatherQuery = new GetCurrentWeatherQuery(1, 1);
var currentWeather = new CurrentWeatherDto();

var validationResutlMock = new Mock<IValidationResult>();
validationResutlMock.SetupGet(x=>x.AnyErrors).Returns(true);
_getCurrentWeatherQueryValidatorMock.Setup(x => x.IsValid(It.IsAny<GetCurrentWeatherQuery>())).Returns(true);
_getCurrentWeatherQueryValidatorMock.Setup(x => x.Validate(It.IsAny<GetCurrentWeatherQuery>())).Returns(new RequestValidationResult { IsValid = true });
_weatherServiceMock.Setup(x => x.GetCurrentWeather(It.IsAny<LocationDto>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Ok(currentWeather));
_currentWeatherValidatorMock.Setup(x => x.Validate(It.IsAny<CurrentWeatherDto>(), It.IsAny<bool>())).Returns(validationResutlMock.Object);
_currentWeatherValidatorMock.Setup(x => x.Validate(It.IsAny<CurrentWeatherDto>())).Returns(new RequestValidationResult { IsValid = false});

//Act
var result = await _uut.HandleAsync(getCurrentWeatherQuery, CancellationToken.None);
Expand All @@ -87,10 +87,9 @@ public async Task CurrentWeather_ValidationFailed()
Assert.Equal(HttpStatusCode.InternalServerError, result.StatusCode);
Assert.Single(result.Errors);
Assert.Null(result.Data);
_getCurrentWeatherQueryValidatorMock.Verify(x => x.IsValid(It.Is<GetCurrentWeatherQuery>(y => y.Equals(getCurrentWeatherQuery))), Times.Once);
_getCurrentWeatherQueryValidatorMock.Verify(x => x.Validate(It.Is<GetCurrentWeatherQuery>(y => y.Equals(getCurrentWeatherQuery))), Times.Once);
_weatherServiceMock.Verify(x => x.GetCurrentWeather(It.Is<LocationDto>(y => y.Equals(getCurrentWeatherQuery.Location)), It.IsAny<CancellationToken>()), Times.Once);
_currentWeatherValidatorMock.Verify(x => x.Validate(It.Is<CurrentWeatherDto>(y=>y.Equals(currentWeather)), It.Is<bool>(y=>!y)), Times.Once);
validationResutlMock.VerifyGet(x=>x.AnyErrors, Times.Once);
_currentWeatherValidatorMock.Verify(x => x.Validate(It.Is<CurrentWeatherDto>(y=>y.Equals(currentWeather))), Times.Once);
_loggerMock.VerifyLog(LogLevel.Error, LogEvents.CurrentWeathersValidation, Times.Once());
}

Expand All @@ -101,11 +100,9 @@ public async Task Success()
var getCurrentWeatherQuery = new GetCurrentWeatherQuery(1, 1);
var currentWeather = new CurrentWeatherDto();

var validationResutlMock = new Mock<IValidationResult>();
validationResutlMock.SetupGet(x => x.AnyErrors).Returns(false);
_getCurrentWeatherQueryValidatorMock.Setup(x => x.IsValid(It.IsAny<GetCurrentWeatherQuery>())).Returns(true);
_getCurrentWeatherQueryValidatorMock.Setup(x => x.Validate(It.IsAny<GetCurrentWeatherQuery>())).Returns(new RequestValidationResult { IsValid = true });
_weatherServiceMock.Setup(x => x.GetCurrentWeather(It.IsAny<LocationDto>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Ok(currentWeather));
_currentWeatherValidatorMock.Setup(x => x.Validate(It.IsAny<CurrentWeatherDto>(), It.IsAny<bool>())).Returns(validationResutlMock.Object);
_currentWeatherValidatorMock.Setup(x => x.Validate(It.IsAny<CurrentWeatherDto>())).Returns(new RequestValidationResult { IsValid = true});

//Act
var result = await _uut.HandleAsync(getCurrentWeatherQuery, CancellationToken.None);
Expand All @@ -115,10 +112,9 @@ public async Task Success()
Assert.Empty(result.Errors);
Assert.NotNull(result.Data);
Assert.Equal(currentWeather, result.Data);
_getCurrentWeatherQueryValidatorMock.Verify(x => x.IsValid(It.Is<GetCurrentWeatherQuery>(y => y.Equals(getCurrentWeatherQuery))), Times.Once);
_getCurrentWeatherQueryValidatorMock.Verify(x => x.Validate(It.Is<GetCurrentWeatherQuery>(y => y.Equals(getCurrentWeatherQuery))), Times.Once);
_weatherServiceMock.Verify(x => x.GetCurrentWeather(It.Is<LocationDto>(y => y.Equals(getCurrentWeatherQuery.Location)), It.IsAny<CancellationToken>()), Times.Once);
_currentWeatherValidatorMock.Verify(x => x.Validate(It.Is<CurrentWeatherDto>(y => y.Equals(currentWeather)), It.Is<bool>(y => !y)), Times.Once);
validationResutlMock.VerifyGet(x => x.AnyErrors, Times.Once);
_currentWeatherValidatorMock.Verify(x => x.Validate(It.Is<CurrentWeatherDto>(y => y.Equals(currentWeather))), Times.Once);
}
}
}
Loading

0 comments on commit f66b34c

Please sign in to comment.