using MediatR; using MediatR.Pipeline; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System.Data.Common; using Tuitio.Domain.Data.DbContexts; using Xunit; namespace Tuitio.Application.Tests.Fixtures { public class DependencyInjectionFixture : IAsyncLifetime { private readonly Guid _prefix; private readonly List _connections; public readonly IServiceProvider ServiceProvider; public DependencyInjectionFixture() { _prefix = Guid.NewGuid(); _connections = new List(); ServiceProvider = BuildServiceProvider(); } public async Task DisposeAsync() { foreach (var con in _connections) await con.DisposeAsync(); } public async Task InitializeAsync() { await PrepareDbAsync(); SeedData(); } private IServiceProvider BuildServiceProvider() { var configurationBuilder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.tuitio.json", optional: true, reloadOnChange: false); var configuration = configurationBuilder.Build(); var services = new ServiceCollection(); services.AddSingleton(configuration); services.AddLogging(builder => { builder.SetMinimumLevel(LogLevel.Warning); builder.AddFilter("Microsoft.*", LogLevel.Warning); }); // MediatR services.AddMediatR(typeof(Application.CommandHandlers.AccountLoginHandler).Assembly); services.AddScoped(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>)); // AutoMapper services.AddAutoMapper(typeof(Application.Mappings.MappingProfile).Assembly); services.AddDbContext(options => { options.UseSqlite(GetOrAddInMemoryDatabase("TuitioDbContext")); options.EnableSensitiveDataLogging(); options.EnableDetailedErrors(); }); services.AddApplicationServices(); var provider = services.BuildServiceProvider(); return provider; } private DbConnection GetOrAddInMemoryDatabase(string code) { var connection = new SqliteConnection($"Data Source={_prefix}{code};Mode=Memory;Cache=shared"); _connections.Add(connection); connection.Open(); return connection; } private async Task PrepareDbAsync() { var result = await ServiceProvider.GetRequiredService().Database.EnsureCreatedAsync(); if (!result) throw new Exception("TuitioDbContext exists"); var script = await File.ReadAllTextAsync("seed.sql"); await ServiceProvider.GetRequiredService().Database.ExecuteSqlRawAsync(script); } private void SeedData() { using var dbContext = ServiceProvider.GetRequiredService(); dbContext.UserStatuses.AddRange(new Domain.Entities.UserStatus[] { new Domain.Entities.UserStatus() { StatusId = 1, StatusCode = "ACTIVE", StatusName = "Active" }, new Domain.Entities.UserStatus() { StatusId = 2, StatusCode = "INACTIVE", StatusName = "Inactive" }, new Domain.Entities.UserStatus() { StatusId = 3, StatusCode = "BLOCKED", StatusName = "Blocked" } }); dbContext.SaveChanges(); } } }