/
afanasevn
/
PdfEncoder
Обзор
Документация
Войти
/
afanasevn
/
PdfEncoder
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
tests/PdfEncoder.IntegrationTests/Support/PdfEncoderWebApplicationFactory.cs
111 строк
4 KB
IBS\NAfanasev
Field validation, integration tests, UI polish
06 июл 2026, 17:18
06 июл 2026, 17:18
0e936b0
Код
Авторство
О чём код?
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.TestHost; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using PdfEncoder.Application.Abstractions; using PdfEncoder.Infrastructure.Persistence; namespace PdfEncoder.IntegrationTests.Support; /// <summary> /// Test host PdfEncoder API с SQLite, temp storage и mock LLM. /// </summary> public class PdfEncoderWebApplicationFactory : WebApplicationFactory<Program>, IAsyncLifetime { private readonly string _databasePath = Path.Combine( Path.GetTempPath(), $"pdfencoder-it-{Guid.NewGuid():N}.db"); private readonly string _storageRoot = Path.Combine( Path.GetTempPath(), $"pdfencoder-it-storage-{Guid.NewGuid():N}"); /// <summary> /// Переопределить в наследнике для тестов SkipLlm (не используется после переноса в pipeline-тест). /// </summary> protected virtual bool SkipLlm => false; /// <summary> /// Mock LLM, зарегистрированный в DI тестового host. /// </summary> public MockLlmClient MockLlm { get; } = new(); /// <summary> /// Сбрасывает БД, storage и счётчики mock LLM между тестами. /// </summary> public async Task ResetStateAsync() { MockLlm.Reset(); if (Directory.Exists(_storageRoot)) { foreach (var file in Directory.EnumerateFiles(_storageRoot)) { File.Delete(file); } } await using var scope = Services.CreateAsyncScope(); var dbContext = scope.ServiceProvider.GetRequiredService<PdfEncoderDbContext>(); await dbContext.Database.EnsureDeletedAsync(); await dbContext.Database.EnsureCreatedAsync(); } /// <inheritdoc /> public async Task InitializeAsync() { Directory.CreateDirectory(_storageRoot); _ = Services; await ResetStateAsync(); } /// <inheritdoc /> public new async Task DisposeAsync() { try { if (File.Exists(_databasePath)) { File.Delete(_databasePath); } if (Directory.Exists(_storageRoot)) { Directory.Delete(_storageRoot, recursive: true); } } catch { // cleanup best-effort } await base.DisposeAsync(); } /// <inheritdoc /> protected override void ConfigureWebHost(IWebHostBuilder builder) { builder.UseEnvironment("Development"); builder.UseSetting("ConnectionStrings:DefaultConnection", $"Data Source={_databasePath}"); builder.UseSetting("Storage:RootPath", _storageRoot); builder.UseSetting("Llm:SkipLlm", SkipLlm ? "true" : "false"); builder.UseSetting("Llm:BaseUrl", "https://integration-test.local/v1"); builder.UseSetting("Llm:ApiKey", "integration-test-key"); builder.UseSetting("Llm:ClassificationModel", "mock/classify"); builder.UseSetting("Llm:ExtractionModel", "mock/extract"); builder.UseSetting("Pipeline:MaxConcurrentJobs", "1"); builder.UseSetting("Cors:AllowedOrigins", "http://localhost:5174"); builder.ConfigureTestServices(services => { services.RemoveAll<IHostedService>(); services.RemoveAll<ILlmClient>(); services.AddScoped<ILlmClient>(_ => MockLlm); }); } }