diff --git a/src/Tests/HttpDebug/debug-tests.http b/src/Tests/HttpDebug/debug-tests.http index b8389a1..9f9828a 100644 --- a/src/Tests/HttpDebug/debug-tests.http +++ b/src/Tests/HttpDebug/debug-tests.http @@ -23,4 +23,8 @@ Content-Type: application/json "latitude": 38.5, "longitude": -78.5 } -} \ No newline at end of file +} + +### add favorites weather request +DELETE https://{{host}}/weather/v1/favorite/1 +Content-Type: application/json \ No newline at end of file diff --git a/src/Tests/Weather.API.UnitTests/Features/AddFavorites/AddFavoriteHandlerTests.cs b/src/Tests/Weather.API.UnitTests/Features/AddFavorites/AddFavoriteHandlerTests.cs index 536575e..95f5ef8 100644 --- a/src/Tests/Weather.API.UnitTests/Features/AddFavorites/AddFavoriteHandlerTests.cs +++ b/src/Tests/Weather.API.UnitTests/Features/AddFavorites/AddFavoriteHandlerTests.cs @@ -22,14 +22,14 @@ public class AddFavoriteHandlerTests private readonly Mock _mapperMock; private readonly Mock> _favoriteLocationEntityDbSetMock; - private readonly IRequestHandler _uut; + private readonly IRequestHandler _uut; public AddFavoriteHandlerTests() { _favoriteLocationEntityDbSetMock = new(); _weatherContextMock = new(); _weatherContextMock.Setup(x => x.FavoriteLocations).Returns(_favoriteLocationEntityDbSetMock.Object); - _addFavoriteCommandValidatorMock = new Mock>(); + _addFavoriteCommandValidatorMock = new(); _loggerMock = new(); _mapperMock = new(); @@ -51,7 +51,6 @@ public async Task InvalidLocation() //Assert Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); Assert.Single(result.Errors); - Assert.False(result.Data); _addFavoriteCommandValidatorMock.Verify(x => x.IsValid(It.Is(y => y.Equals(addFavoriteCommand))), Times.Once); } @@ -72,7 +71,6 @@ public async Task AddFavoriteLocation_Failed() //Assert Assert.Equal(HttpStatusCode.InternalServerError, result.StatusCode); Assert.Single(result.Errors); - Assert.False(result.Data); _addFavoriteCommandValidatorMock.Verify(x => x.IsValid(It.Is(y => y.Equals(addFavoriteCommand))), Times.Once); _loggerMock.VerifyLog(LogLevel.Error, LogEvents.FavoriteWeathersStoreToDatabase, Times.Once()); } @@ -96,7 +94,6 @@ public async Task Success() //Assert Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Empty(result.Errors); - Assert.True(result.Data); _addFavoriteCommandValidatorMock.Verify(x => x.IsValid(It.Is(y => y.Equals(addFavoriteCommand))), Times.Once); _favoriteLocationEntityDbSetMock.Verify(x => x.AddAsync(It.IsAny(), It.IsAny()), Times.Once); } diff --git a/src/Tests/Weather.API.UnitTests/Features/DeleteFavorites/DeleteFavoriteHandlerTests.cs b/src/Tests/Weather.API.UnitTests/Features/DeleteFavorites/DeleteFavoriteHandlerTests.cs new file mode 100644 index 0000000..c375773 --- /dev/null +++ b/src/Tests/Weather.API.UnitTests/Features/DeleteFavorites/DeleteFavoriteHandlerTests.cs @@ -0,0 +1,91 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using Moq; +using System.Net; +using Validot; +using Weather.API.Domain.Abstractions; +using Weather.API.Domain.Database.Entities; +using Weather.API.Features.DeleteFavorites; +using Weather.API.UnitTests.Domain.Database; + + +namespace Weather.API.UnitTests.Features.DeleteFavorites +{ + public class DeleteFavoriteHandlerTests + { + private readonly Mock> _deleteFavoriteCommandValidatorMock; + private readonly Mock _weatherContextMock; + private readonly Mock> _favoriteLocationEntityDbSetMock; + + private readonly IRequestHandler _uut; + public DeleteFavoriteHandlerTests() + { + _deleteFavoriteCommandValidatorMock = new(); + var loggerMock = new Mock>(); + _weatherContextMock = new(); + _favoriteLocationEntityDbSetMock = new(); + + _uut = new DeleteFavoriteHandler(_deleteFavoriteCommandValidatorMock.Object, loggerMock.Object, _weatherContextMock.Object); + } + + [Fact] + public async Task InvalidRequest() + { + //Arrange + var deleteFavoriteCommand = new DeleteFavoriteCommand { Id = 1 }; + + _deleteFavoriteCommandValidatorMock.Setup(x => x.IsValid(deleteFavoriteCommand)).Returns(false); + + //Act + var result = await _uut.HandleAsync(deleteFavoriteCommand, CancellationToken.None); + + //Assert + Assert.Equal(HttpStatusCode.BadRequest, result.StatusCode); + Assert.Single(result.Errors); + Assert.False(result.Data); + } + + [Fact] + public async Task DeleteFavoriteLocationSafeAsync_Failed() + { + //Arrange + var deleteFavoriteCommand = new DeleteFavoriteCommand { Id = 1 }; + + _deleteFavoriteCommandValidatorMock.Setup(x => x.IsValid(deleteFavoriteCommand)).Returns(true); + + _favoriteLocationEntityDbSetMock.Setup(x => x.FindAsync(It.IsAny(), CancellationToken.None)).ThrowsAsync(new DbUpdateException()); + _weatherContextMock.Setup(x => x.FavoriteLocations).Returns(_favoriteLocationEntityDbSetMock.Object); + + //Act + var result = await _uut.HandleAsync(deleteFavoriteCommand, CancellationToken.None); + + //Assert + Assert.Equal(HttpStatusCode.InternalServerError, result.StatusCode); + Assert.Single(result.Errors); + Assert.False(result.Data); + } + + [Fact] + public async Task Success() + { + //Arrange + var deleteFavoriteCommand = new DeleteFavoriteCommand { Id = 1 }; + + _deleteFavoriteCommandValidatorMock.Setup(x => x.IsValid(deleteFavoriteCommand)).Returns(true); + + var favoriteLocation = new FavoriteLocationEntity(); + _favoriteLocationEntityDbSetMock.Setup(x => x.FindAsync(It.IsAny(), CancellationToken.None)).ReturnsAsync(favoriteLocation); + _favoriteLocationEntityDbSetMock.Setup(x => x.Remove(favoriteLocation)); + _weatherContextMock.Setup(x => x.FavoriteLocations).Returns(_favoriteLocationEntityDbSetMock.Object); + + //Act + var result = await _uut.HandleAsync(deleteFavoriteCommand, CancellationToken.None); + + //Assert + Assert.Equal(HttpStatusCode.OK, result.StatusCode); + Assert.Empty(result.Errors); + Assert.True(result.Data); + } + + } +} diff --git a/src/Tests/Weather.API.UnitTests/Features/GetFavorites/GetFavoritesHandlerTests.cs b/src/Tests/Weather.API.UnitTests/Features/GetFavorites/GetFavoritesHandlerTests.cs index 3d37c29..adb0069 100644 --- a/src/Tests/Weather.API.UnitTests/Features/GetFavorites/GetFavoritesHandlerTests.cs +++ b/src/Tests/Weather.API.UnitTests/Features/GetFavorites/GetFavoritesHandlerTests.cs @@ -35,7 +35,6 @@ public GetFavoritesHandlerTests() _currentWeatherValidatorMock = new(); _weatherContextMock = new(); _mapperMock = new(); - _favoriteLocationEntityDbSetMock = new(); _uut = new GetFavoritesHandler( @@ -94,11 +93,10 @@ public async Task EmptyResult_GetCurrentWeather_Fail() var favoriteLocations = new List() { new() }; _favoriteLocationEntityDbSetMock.SetupMock(favoriteLocations); _weatherContextMock.Setup(x => x.FavoriteLocations).Returns(_favoriteLocationEntityDbSetMock.Object); - _mapperMock.Setup(x => x.Map>(favoriteLocations)).Returns(new List { locationDto }); - + _mapperMock.Setup(x => x.Map(It.IsAny())).Returns(locationDto); _locationValidatorMock.Setup(x => x.IsValid(It.IsAny())).Returns(true); - _weatherServiceMock.Setup(x => x.GetCurrentWeather(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Fail(failMessage)); + //Act var result = await _uut.HandleAsync(EmptyRequest.Instance, CancellationToken.None); @@ -117,11 +115,11 @@ public async Task One_Of_GetCurrentWeather_Failed() var failMessage = "Some fail message"; var locationDto = new LocationDto { Latitude = 1, Longitude = 1 }; - var favoriteLocations = new List() { new() }; + var favoriteLocations = new List { new(), new FavoriteLocationEntity { Latitude = locationDto.Latitude, Longitude = locationDto.Longitude } }; _favoriteLocationEntityDbSetMock.SetupMock(favoriteLocations); _weatherContextMock.Setup(x => x.FavoriteLocations).Returns(_favoriteLocationEntityDbSetMock.Object); - _mapperMock.Setup(x => x.Map>(favoriteLocations)).Returns(new List { locationDto, new() }); - + _mapperMock.Setup(x => x.Map(It.Is(y=> y.Latitude!= locationDto.Latitude))).Returns(new LocationDto()); + _mapperMock.Setup(x => x.Map(It.Is(y => y.Latitude == locationDto.Latitude))).Returns(locationDto); _locationValidatorMock.Setup(x => x.IsValid(It.IsAny())).Returns(true); var currentWeather = new CurrentWeatherDto(); @@ -138,7 +136,6 @@ public async Task One_Of_GetCurrentWeather_Failed() Assert.Single(result.Errors); Assert.NotNull(result.Data); Assert.Single(result.Data.FavoriteWeathers); - Assert.Equal(currentWeather, result.Data.FavoriteWeathers.Single()); _weatherServiceMock.Verify(x => x.GetCurrentWeather(It.IsAny(), It.IsAny()), Times.Exactly(2)); _loggerMock.VerifyLog(LogLevel.Warning, LogEvents.FavoriteWeathersGeneral, failMessage, Times.Once()); _locationValidatorMock.Verify(x => x.IsValid(It.Is(y => y.Equals(locationDto))), Times.Once); @@ -154,7 +151,7 @@ public async Task GetCurrentWeather_Validation_Fail() var favoriteLocations = new List() { new() }; _favoriteLocationEntityDbSetMock.SetupMock(favoriteLocations); _weatherContextMock.Setup(x => x.FavoriteLocations).Returns(_favoriteLocationEntityDbSetMock.Object); - _mapperMock.Setup(x => x.Map>(favoriteLocations)).Returns(new List { locationDto }); + _mapperMock.Setup(x => x.Map(It.IsAny())).Returns(locationDto); _locationValidatorMock.Setup(x => x.IsValid(It.IsAny())).Returns(true); _currentWeatherValidatorMock.Setup(x => x.IsValid(It.IsAny())).Returns(false); @@ -182,7 +179,7 @@ public async Task Success() var favoriteLocations = new List() { new() }; _favoriteLocationEntityDbSetMock.SetupMock(favoriteLocations); _weatherContextMock.Setup(x => x.FavoriteLocations).Returns(_favoriteLocationEntityDbSetMock.Object); - _mapperMock.Setup(x => x.Map>(favoriteLocations)).Returns(new List { locationDto }); + _mapperMock.Setup(x => x.Map(It.IsAny())).Returns(locationDto); _locationValidatorMock.Setup(x => x.IsValid(It.IsAny())).Returns(true); _currentWeatherValidatorMock.Setup(x => x.IsValid(It.IsAny())).Returns(true); @@ -197,7 +194,6 @@ public async Task Success() Assert.Empty(result.Errors); Assert.NotNull(result.Data); Assert.Single(result.Data.FavoriteWeathers); - Assert.Equal(currentWeather, result.Data.FavoriteWeathers.Single()); _weatherServiceMock.Verify(x => x.GetCurrentWeather(It.Is(y => y.Equals(locationDto)), It.IsAny()), Times.Once); _locationValidatorMock.Verify(x => x.IsValid(It.Is(y => y.Equals(locationDto))), Times.Once); _currentWeatherValidatorMock.Verify(x => x.IsValid(It.Is(y => y.Equals(currentWeather))), Times.Once); diff --git a/src/Weather.API/Domain/Dtos/CurrentWeatherDto.cs b/src/Weather.API/Domain/Dtos/CurrentWeatherDto.cs index 171de1b..7cc548f 100644 --- a/src/Weather.API/Domain/Dtos/CurrentWeatherDto.cs +++ b/src/Weather.API/Domain/Dtos/CurrentWeatherDto.cs @@ -1,6 +1,6 @@ namespace Weather.API.Domain.Dtos { - public sealed class CurrentWeatherDto + public class CurrentWeatherDto { public double Temperature { get; init; } diff --git a/src/Weather.API/Features/AddFavorites/AddFavoriteHandler.cs b/src/Weather.API/Features/AddFavorites/AddFavoriteHandler.cs index fbc2793..fdb4eba 100644 --- a/src/Weather.API/Features/AddFavorites/AddFavoriteHandler.cs +++ b/src/Weather.API/Features/AddFavorites/AddFavoriteHandler.cs @@ -13,7 +13,7 @@ namespace Weather.API.Features.Favorites.AddFavorites { - internal sealed class AddFavoriteHandler : IRequestHandler + internal sealed class AddFavoriteHandler : IRequestHandler { private readonly IMapper _mapper; private readonly WeatherContext _weatherContext; @@ -31,20 +31,20 @@ public AddFavoriteHandler( _mapper = Guard.Against.Null(mapper); } - public async Task> HandleAsync(AddFavoriteCommand request, CancellationToken cancellationToken) + public async Task> HandleAsync(AddFavoriteCommand request, CancellationToken cancellationToken) { if (!_addFavoriteCommandValidator.IsValid(request)) { - return HttpDataResponses.AsBadRequest(string.Format(ErrorMessages.RequestValidationError, request)); + return HttpDataResponses.AsBadRequest(string.Format(ErrorMessages.RequestValidationError, request)); } var addResult = await AddFavoriteLocationSafeAsync(request, cancellationToken); if (addResult.IsFailed) { - return HttpDataResponses.AsInternalServerError("Location was not stored in database."); + return HttpDataResponses.AsInternalServerError("Location was not stored in database."); } - return HttpDataResponses.AsOK(true); + return HttpDataResponses.AsOK(addResult.Value); } public async Task> AddFavoriteLocationSafeAsync(AddFavoriteCommand addFavoriteCommand, CancellationToken cancellationToken) diff --git a/src/Weather.API/Features/AddFavorites/ContainerConfigurationExtension.cs b/src/Weather.API/Features/AddFavorites/ContainerConfigurationExtension.cs index 2d8e850..a0fe864 100644 --- a/src/Weather.API/Features/AddFavorites/ContainerConfigurationExtension.cs +++ b/src/Weather.API/Features/AddFavorites/ContainerConfigurationExtension.cs @@ -12,9 +12,9 @@ public static class ContainerConfigurationExtension public static IEndpointRouteBuilder BuildAddFavoriteWeatherEndpoints(this IEndpointRouteBuilder endpointRouteBuilder) { endpointRouteBuilder.MapPost("v1/favorite", - async ([FromBody] AddFavoriteCommand addFavoriteCommand, [FromServices] IRequestHandler handler, CancellationToken cancellationToken) => + async ([FromBody] AddFavoriteCommand addFavoriteCommand, [FromServices] IRequestHandler handler, CancellationToken cancellationToken) => await handler.SendAsync(addFavoriteCommand, cancellationToken)) - .Produces>() + .Produces>() .WithName("AddFavorite") .WithTags("Setters"); @@ -23,7 +23,7 @@ await handler.SendAsync(addFavoriteCommand, cancellationToken)) public static IServiceCollection AddAddFavorites(this IServiceCollection serviceCollection) => serviceCollection - .AddScoped, AddFavoriteHandler>() + .AddScoped, AddFavoriteHandler>() .AddValidotSingleton, AddFavoriteCommandSpecificationHolder, AddFavoriteCommand>(); } diff --git a/src/Weather.API/Features/DeleteFavorites/ContainerConfigurationExtension.cs b/src/Weather.API/Features/DeleteFavorites/ContainerConfigurationExtension.cs new file mode 100644 index 0000000..b4b4210 --- /dev/null +++ b/src/Weather.API/Features/DeleteFavorites/ContainerConfigurationExtension.cs @@ -0,0 +1,29 @@ +using Microsoft.AspNetCore.Mvc; +using Validot; +using Weather.API.Domain.Abstractions; +using Weather.API.Domain.Extensions; +using WeatherApi.Domain.Http; + +namespace Weather.API.Features.DeleteFavorites +{ + public static class ContainerConfigurationExtension + { + public static IEndpointRouteBuilder BuildDeleteFavoriteWeatherEndpoints(this IEndpointRouteBuilder endpointRouteBuilder) + { + endpointRouteBuilder.MapDelete("v1/favorite/{id}", + async (int id, [FromServices] IRequestHandler handler, CancellationToken cancellationToken) => + await handler.SendAsync(new DeleteFavoriteCommand { Id = id }, cancellationToken)) + .Produces>() + .WithName("DeleteFavorite") + .WithTags("Delete"); + + return endpointRouteBuilder; + } + + public static IServiceCollection AddDeleteFavorites(this IServiceCollection serviceCollection) + => serviceCollection + .AddScoped, DeleteFavoriteHandler>() + .AddValidotSingleton, DeleteFavoriteCommandSpecificationHolder, DeleteFavoriteCommand>(); + + } +} diff --git a/src/Weather.API/Features/DeleteFavorites/DeleteFavoriteCommand.cs b/src/Weather.API/Features/DeleteFavorites/DeleteFavoriteCommand.cs new file mode 100644 index 0000000..4f0ab2d --- /dev/null +++ b/src/Weather.API/Features/DeleteFavorites/DeleteFavoriteCommand.cs @@ -0,0 +1,7 @@ +namespace Weather.API.Features.DeleteFavorites +{ + internal sealed class DeleteFavoriteCommand + { + public int Id { get; init; } + } +} diff --git a/src/Weather.API/Features/DeleteFavorites/DeleteFavoriteCommandSpecificationHolder.cs b/src/Weather.API/Features/DeleteFavorites/DeleteFavoriteCommandSpecificationHolder.cs new file mode 100644 index 0000000..edcd8ce --- /dev/null +++ b/src/Weather.API/Features/DeleteFavorites/DeleteFavoriteCommandSpecificationHolder.cs @@ -0,0 +1,17 @@ +using Validot; + +namespace Weather.API.Features.DeleteFavorites +{ + internal sealed class DeleteFavoriteCommandSpecificationHolder : ISpecificationHolder + { + public Specification Specification { get; } + + public DeleteFavoriteCommandSpecificationHolder() + { + Specification addFavoriteCommandSpecification = s => s + .Member(m => m.Id, r => r.NonNegative()); + + Specification = addFavoriteCommandSpecification; + } + } +} diff --git a/src/Weather.API/Features/DeleteFavorites/DeleteFavoriteHandler.cs b/src/Weather.API/Features/DeleteFavorites/DeleteFavoriteHandler.cs new file mode 100644 index 0000000..37854e9 --- /dev/null +++ b/src/Weather.API/Features/DeleteFavorites/DeleteFavoriteHandler.cs @@ -0,0 +1,61 @@ +using Ardalis.GuardClauses; +using FluentResults; +using Microsoft.EntityFrameworkCore; +using Validot; +using Weather.API.Domain.Abstractions; +using Weather.API.Domain.Database.EFContext; +using Weather.API.Domain.Extensions; +using Weather.API.Domain.Logging; +using Weather.API.Domain.Resources; +using WeatherApi.Domain.Http; + +namespace Weather.API.Features.DeleteFavorites +{ + internal sealed class DeleteFavoriteHandler : IRequestHandler + { + private readonly WeatherContext _weatherContext; + private readonly IValidator _validator; + private readonly ILogger _logger; + public DeleteFavoriteHandler( + IValidator validator, + ILogger logger, + WeatherContext weatherContext) + { + _validator = Guard.Against.Null(validator); + _logger = Guard.Against.Null(logger); + _weatherContext = Guard.Against.Null(weatherContext); + } + + public async Task> HandleAsync(DeleteFavoriteCommand request, CancellationToken cancellationToken) + { + if (!_validator.IsValid(request)) + { + return HttpDataResponses.AsBadRequest(string.Format(ErrorMessages.RequestValidationError, request)); + } + + var addResult = await DeleteFavoriteLocationSafeAsync(request, cancellationToken); + if (addResult.IsFailed) + { + return HttpDataResponses.AsInternalServerError("Location was not deleted from database."); + } + + return HttpDataResponses.AsOK(true); + } + + public async Task DeleteFavoriteLocationSafeAsync(DeleteFavoriteCommand command, CancellationToken cancellationToken) + { + try + { + var location = await _weatherContext.FavoriteLocations.FindAsync(command.Id, cancellationToken); + _weatherContext.Remove(location!); + await _weatherContext.SaveChangesAsync(cancellationToken); + return Result.Ok(); + } + catch (DbUpdateException ex) + { + _logger.LogError(LogEvents.FavoriteWeathersStoreToDatabase, ex, "Can't delete location."); + return Result.Fail(ex.Message); + } + } + } +} diff --git a/src/Weather.API/Features/GetFavorites/FavoriteCurrentWeatherDto.cs b/src/Weather.API/Features/GetFavorites/FavoriteCurrentWeatherDto.cs new file mode 100644 index 0000000..94ed444 --- /dev/null +++ b/src/Weather.API/Features/GetFavorites/FavoriteCurrentWeatherDto.cs @@ -0,0 +1,10 @@ + +using Weather.API.Domain.Dtos; + +namespace Weather.API.Features.GetFavorites +{ + public sealed class FavoriteCurrentWeatherDto : CurrentWeatherDto + { + public int Id { get; init; } + } +} diff --git a/src/Weather.API/Features/GetFavorites/FavoritesWeatherDto.cs b/src/Weather.API/Features/GetFavorites/FavoritesWeatherDto.cs index 062bdf8..680a2ca 100644 --- a/src/Weather.API/Features/GetFavorites/FavoritesWeatherDto.cs +++ b/src/Weather.API/Features/GetFavorites/FavoritesWeatherDto.cs @@ -1,9 +1,9 @@ -using Weather.API.Domain.Dtos; +using Weather.API.Features.GetFavorites; namespace Weather.API.Features.Favorites.GetFavorites { public sealed class FavoritesWeatherDto { - public IReadOnlyCollection FavoriteWeathers { get; init; } = new List(); + public IReadOnlyCollection FavoriteWeathers { get; init; } = new List(); } } diff --git a/src/Weather.API/Features/GetFavorites/GetFavoritesHandler.cs b/src/Weather.API/Features/GetFavorites/GetFavoritesHandler.cs index c042b64..9585338 100644 --- a/src/Weather.API/Features/GetFavorites/GetFavoritesHandler.cs +++ b/src/Weather.API/Features/GetFavorites/GetFavoritesHandler.cs @@ -5,10 +5,12 @@ using Validot; using Weather.API.Domain.Abstractions; using Weather.API.Domain.Database.EFContext; +using Weather.API.Domain.Database.Entities; using Weather.API.Domain.Dtos; using Weather.API.Domain.Extensions; using Weather.API.Domain.Logging; using Weather.API.Domain.Resources; +using Weather.API.Features.GetFavorites; using WeatherApi.Domain.Http; namespace Weather.API.Features.Favorites.GetFavorites @@ -40,7 +42,7 @@ public GetFavoritesHandler( public async Task> HandleAsync(EmptyRequest request, CancellationToken cancellationToken) { - var favoriteLocations = await GetFavoritesAync(cancellationToken); + var favoriteLocations = await _weatherContext.FavoriteLocations.ToListAsync(cancellationToken); if (!favoriteLocations.HasAny()) { @@ -51,14 +53,14 @@ public async Task> HandleAsync(EmptyReques } - private async Task> GetFavoritesAsync(IEnumerable favoriteLocationsResult, CancellationToken cancellationToken) + private async Task> GetFavoritesAsync(IEnumerable favoriteLocationsResult, CancellationToken cancellationToken) { - var result = new List(); + var result = new List(); var errorMessages = new List(); await favoriteLocationsResult.ForEachAsync(async (location) => { - var favoriteWeather = await GetWeatherAsync(location, cancellationToken); + var favoriteWeather = await GetWeatherAsync(_mapper.Map(location), cancellationToken); if (favoriteWeather.IsFailed) { @@ -66,7 +68,15 @@ await favoriteLocationsResult.ForEachAsync(async (location) => return; } - result.Add(favoriteWeather.Value); + result.Add(new FavoriteCurrentWeatherDto + { + CityName = favoriteWeather.Value.CityName, + DateTime = favoriteWeather.Value.DateTime, + Sunrise = favoriteWeather.Value.Sunrise, + Sunset = favoriteWeather.Value.Sunset, + Id = location.Id, + Temperature = favoriteWeather.Value.Temperature + }); }); return result.Any() ? diff --git a/src/Weather.API/Program.cs b/src/Weather.API/Program.cs index 90f7d2e..ef48b6d 100644 --- a/src/Weather.API/Program.cs +++ b/src/Weather.API/Program.cs @@ -1,5 +1,6 @@ using Weather.API.Configuration; using Weather.API.Features.AddFavorites; +using Weather.API.Features.DeleteFavorites; using Weather.API.Features.Favorites.AddFavorites; using Weather.API.Features.Favorites.GetFavorites; using Weather.API.Features.GetFavorites; @@ -14,7 +15,8 @@ .AddAddFavorites() .AddGetFavorites() .AddGetCurrentWeather() - .AddGetForecastWeather(); + .AddGetForecastWeather() + .AddDeleteFavorites(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); @@ -36,6 +38,7 @@ .BuildAddFavoriteWeatherEndpoints() .BuildGetFavoriteWeatherEndpoints() .BuildGetForecastWeatherEndpoints() - .BuildGetCurrentWeatherEndpoints(); + .BuildGetCurrentWeatherEndpoints() + .BuildDeleteFavoriteWeatherEndpoints(); app.Run(); \ No newline at end of file