using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using RacePlannerApi.Data; using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text.Json; using Xunit; namespace backend.Tests.Integration; public class CustomWebApplicationFactory : WebApplicationFactory { protected override void ConfigureWebHost(IWebHostBuilder builder) { builder.ConfigureServices(services => { // Remove all DbContextOptions registrations var descriptors = services.Where( d => d.ServiceType == typeof(DbContextOptions) || d.ServiceType.Name.Contains("DbContextOptions")).ToList(); foreach (var descriptor in descriptors) { services.Remove(descriptor); } // Add in-memory database services.AddDbContext(options => { options.UseInMemoryDatabase(Guid.NewGuid().ToString()); }); }); } } public abstract class IntegrationTestBase : IClassFixture, IDisposable { protected readonly CustomWebApplicationFactory _factory; protected readonly HttpClient _client; protected readonly JsonSerializerOptions _jsonOptions = new(JsonSerializerDefaults.Web); protected readonly IServiceScope _scope; protected readonly RacePlannerDbContext _dbContext; protected IntegrationTestBase(CustomWebApplicationFactory factory) { _factory = factory; _client = _factory.CreateClient(); _scope = _factory.Services.CreateScope(); _dbContext = _scope.ServiceProvider.GetRequiredService(); _dbContext.Database.EnsureCreated(); } public void Dispose() { _scope.Dispose(); } protected HttpClient CreateAuthenticatedClient(string token = "") { var client = _factory.CreateClient(); if (!string.IsNullOrEmpty(token)) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); } return client; } protected async Task GetAsync(string url) { var response = await _client.GetAsync(url); response.EnsureSuccessStatusCode(); return await response.Content.ReadFromJsonAsync(_jsonOptions); } protected async Task PostAsync(string url, TRequest data) { var response = await _client.PostAsJsonAsync(url, data, _jsonOptions); response.EnsureSuccessStatusCode(); return await response.Content.ReadFromJsonAsync(_jsonOptions); } protected async Task PutAsync(string url, TRequest data) { var response = await _client.PutAsJsonAsync(url, data, _jsonOptions); response.EnsureSuccessStatusCode(); return await response.Content.ReadFromJsonAsync(_jsonOptions); } protected async Task DeleteAsync(string url) { var response = await _client.DeleteAsync(url); response.EnsureSuccessStatusCode(); } }