using FluentAssertions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using System.Net; using System.Net.Http.Json; using Vegasco.WebApi.Cars; using Vegasco.WebApi.Consumptions; using Vegasco.WebApi.Persistence; namespace WebApi.Tests.Integration.Consumptions; [Collection(SharedTestCollection.Name)] public class CreateConsumptionTests : IAsyncLifetime { private readonly WebAppFactory _factory; private readonly IServiceScope _scope; private readonly ApplicationDbContext _dbContext; private readonly CarFaker _carFaker = new(); private readonly ConsumptionFaker _consumptionFaker = new(); public CreateConsumptionTests(WebAppFactory factory) { _factory = factory; _scope = _factory.Services.CreateScope(); _dbContext = _scope.ServiceProvider.GetRequiredService(); } [Fact] public async Task CreateConsumption_ShouldCreateConsumption_WhenRequestIsValid() { // Arrange CreateCar.Response createdCarResponse = await CreateCarAsync(); CreateConsumption.Request createConsumptionRequest = _consumptionFaker.CreateConsumptionRequest(createdCarResponse.Id); // Act using HttpResponseMessage response = await _factory.HttpClient.PostAsJsonAsync("v1/consumptions", createConsumptionRequest); // Assert response.StatusCode.Should().Be(HttpStatusCode.Created); var createdConsumption = await response.Content.ReadFromJsonAsync(); createdConsumption.Should().BeEquivalentTo(createConsumptionRequest, o => o.ExcludingMissingMembers()); _dbContext.Consumptions.Should().HaveCount(1) .And.ContainEquivalentOf(createdConsumption, o => o.ExcludingMissingMembers() .Excluding(x => x!.Id) .Excluding(x => x!.CarId)); Consumption singleConsumption = _dbContext.Consumptions.Single(); singleConsumption.Id.Value.Should().Be(createdConsumption!.Id); singleConsumption.CarId.Value.Should().Be(createdConsumption.CarId); } [Fact] public async Task CreateConsumption_ShouldReturnValidationProblems_WhenRequestIsInvalid() { // Arrange CreateConsumption.Request createConsumptionRequest = _consumptionFaker.CreateConsumptionRequest(Guid.Empty); // Act using HttpResponseMessage response = await _factory.HttpClient.PostAsJsonAsync("v1/consumptions", createConsumptionRequest); // Assert response.StatusCode.Should().Be(HttpStatusCode.BadRequest); var validationProblemDetails = await response.Content.ReadFromJsonAsync(); validationProblemDetails!.Errors.Keys.Should().Contain(x => x.Equals(nameof(createConsumptionRequest.CarId), StringComparison.OrdinalIgnoreCase)); _dbContext.Consumptions.Should().NotContainEquivalentOf(createConsumptionRequest, o => o.ExcludingMissingMembers()); } private async Task CreateCarAsync() { CreateCar.Request createCarRequest = new CarFaker().CreateCarRequest(); using HttpResponseMessage createCarResponse = await _factory.HttpClient.PostAsJsonAsync("v1/cars", createCarRequest); createCarResponse.EnsureSuccessStatusCode(); var createdCarResponse = await createCarResponse.Content.ReadFromJsonAsync(); return createdCarResponse!; } public Task InitializeAsync() { FluentAssertionConfiguration.SetupGlobalConfig(); return Task.CompletedTask; } public async Task DisposeAsync() { _scope.Dispose(); await _dbContext.DisposeAsync(); await _factory.ResetDatabaseAsync(); } }