Рефакторинг инфраструктуры для тестов

This commit is contained in:
Степанов Дмитрий 2024-03-11 13:16:07 +03:00
parent 7867001610
commit 18c6cb316f
5 changed files with 131 additions and 163 deletions

View File

@ -4,15 +4,23 @@ using Xunit;
namespace AsbCloudWebApi.IntegrationTests; namespace AsbCloudWebApi.IntegrationTests;
public abstract class BaseIntegrationTest : IClassFixture<WebAppFactoryFixture> public abstract class BaseIntegrationTest : IClassFixture<WebAppFactoryFixture>,
IDisposable
{ {
protected readonly IServiceScope scope; protected readonly IServiceScope scope;
protected readonly IAsbCloudDbContext dbContext; protected readonly AsbCloudDbContext dbContext;
protected BaseIntegrationTest(WebAppFactoryFixture factory) protected BaseIntegrationTest(WebAppFactoryFixture factory)
{ {
scope = factory.Services.CreateScope(); scope = factory.Services.CreateScope();
dbContext = scope.ServiceProvider.GetRequiredService<IAsbCloudDbContext>();
dbContext = scope.ServiceProvider.GetRequiredService<AsbCloudDbContext>();
}
public void Dispose()
{
scope.Dispose();
dbContext.Dispose();
} }
} }

View File

@ -2,110 +2,55 @@
namespace AsbCloudWebApi.IntegrationTests.Data namespace AsbCloudWebApi.IntegrationTests.Data
{ {
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2211:Поля, не являющиеся константами, не должны быть видимыми", Justification = "<Ожидание>")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2211:Поля, не являющиеся константами, не должны быть видимыми",
public static class Defaults Justification = "<Ожидание>")]
{ public static class Defaults
public static Driller[] Drillers = new Driller[] {
{ public static SimpleTimezone Timezone => new()
new() {
{ Hours = 1
Id = 1, };
Name = "test1",
Surname = "test1",
Patronymic = "test1"
},
new()
{
Id = 2,
Name = "test2",
Surname = "test2",
Patronymic = "test2"
}
};
public static WellOperation[] WellOperations = new WellOperation[] public static Deposit[] Deposits => new Deposit[]
{ {
new() new()
{ {
Id = 1, Caption = "Deposit1",
IdWell = 1, Latitude = 10,
IdType = 1, Longitude = 20,
DateStart = DateTimeOffset.UtcNow.AddDays(-1), Timezone = Timezone,
CategoryInfo = "1", Clusters = new[]
Comment = "1", {
DepthEnd = 20, new Cluster
DepthStart = 10, {
DurationHours = 1, Caption = "Cluster1",
IdCategory = 5000, Latitude = 10,
IdPlan = null, Longitude = 20,
IdUser = 1, Timezone = Timezone,
IdWellSectionType = 1, Wells = new[]
LastUpdateDate = DateTimeOffset.UtcNow {
} new Well
}; {
IdWellType = 1,
public static Deposit[] Deposits = new Deposit[] { IdState = 1,
new() Caption = "Well1",
{ Latitude = 10,
Id = 1, Longitude = 20,
Caption = "Deposit1", Timezone = Timezone,
Latitude = 10, Telemetry = new Telemetry
Longitude = 20, {
Timezone = GetTimezone() RemoteUid = "555-555-555",
} TimeZone = Timezone
}; },
RelationCompaniesWells = new RelationCompanyWell[]
public static Cluster[] Clusters = new Cluster[] { {
new() new() { IdCompany = 1 },
{ },
Id = 1, }
IdDeposit = Deposits[0].Id, }
Caption = "Cluster1", }
Latitude = 10, }
Longitude = 20, }
Timezone = GetTimezone() };
} }
}; }
public static Telemetry[] Telemetries = new Telemetry[]
{
new()
{
Id = 1,
RemoteUid = "555-555-555",
TimeZone = GetTimezone()
}
};
public static Well[] Wells = new Well[] {
new()
{
Id = 1,
IdCluster = Clusters[0].Id,
IdWellType = 1,
IdState = 1,
Caption = "Well1",
Latitude = 10,
Longitude = 20,
IdTelemetry = Telemetries[0].Id,
Timezone = GetTimezone()
}
};
public static RelationCompanyWell[] RelationsCompanyWell = new RelationCompanyWell[]
{
new() { IdCompany = 1, IdWell = Wells[0].Id },
};
public static RelationUserUserRole[] RelationsUserUserRole = new RelationUserUserRole[]
{
new(){ IdUserRole= 1, IdUser = 1}
};
private static SimpleTimezone GetTimezone() =>
new ()
{
Hours = 1
};
}
}

View File

@ -0,0 +1,15 @@
namespace AsbCloudWebApi.IntegrationTests;
public class DbConnection
{
public string Host { get; set; } = null!;
public int Port { get; set; }
public string Username { get; set; } = null!;
public string Password { get; set; } = null!;
public string GetConnectionString() =>
$"Host={Host};Database={Guid.NewGuid()};Port={Port};Username={Username};Password={Password};Persist Security Info=True;Include Error Detail=True";
}

View File

@ -1,4 +1,3 @@
using AsbCloudDb;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.Mvc.Testing;
@ -8,87 +7,80 @@ using Microsoft.Extensions.DependencyInjection;
using Refit; using Refit;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Text.Json; using System.Text.Json;
using AsbCloudDb;
using AsbCloudWebApi.IntegrationTests.Converters; using AsbCloudWebApi.IntegrationTests.Converters;
using Xunit;
namespace AsbCloudWebApi.IntegrationTests; namespace AsbCloudWebApi.IntegrationTests;
public class WebAppFactoryFixture : WebApplicationFactory<Startup>, public class WebAppFactoryFixture : WebApplicationFactory<Startup>,
IAsyncLifetime IDisposable
{ {
private static readonly JsonSerializerOptions jsonSerializerOptions = new() private static readonly JsonSerializerOptions JsonSerializerOptions = new()
{ {
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true, PropertyNameCaseInsensitive = true,
Converters = { new ValidationResultConverter() } Converters = { new ValidationResultConverter() }
}; };
private static readonly RefitSettings refitSettings = new RefitSettings(new SystemTextJsonContentSerializer(jsonSerializerOptions)); private static readonly RefitSettings RefitSettings = new(new SystemTextJsonContentSerializer(JsonSerializerOptions));
protected override void ConfigureWebHost(IWebHostBuilder builder) protected override void ConfigureWebHost(IWebHostBuilder builder)
{ {
var configuration = new ConfigurationBuilder() var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.Tests.json")
.Build(); .Build();
var connectionString = configuration.GetConnectionString("TestConnection")!;
builder.ConfigureServices(services => var dbConnection = configuration.GetSection("DbConnection").Get<DbConnection>();
var connectionString = dbConnection?.GetConnectionString();
builder.ConfigureServices(services =>
{ {
var descriptor = services.FirstOrDefault(d => d.ServiceType == typeof(DbContextOptions<AsbCloudDbContext>)); var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<AsbCloudDbContext>));
if (descriptor is not null) if (descriptor != null)
services.Remove(descriptor); services.Remove(descriptor);
services.AddDbContext<AsbCloudDbContext>(options => services.AddDbContext<AsbCloudDbContext>(options =>
options.UseNpgsql(connectionString)); options.UseNpgsql(connectionString));
var serviceProvider = services.BuildServiceProvider();
using var scope = serviceProvider.CreateScope();
var scopedServices = scope.ServiceProvider;
var dbContext = scopedServices.GetRequiredService<AsbCloudDbContext>();
dbContext.Database.EnsureCreatedAndMigrated();
dbContext.Deposits.AddRange(Data.Defaults.Deposits);
dbContext.SaveChanges();
}); });
} }
public async Task InitializeAsync() public new void Dispose()
{ {
using var scope = Services.CreateScope(); using var scope = Services.CreateScope();
var scopedServices = scope.ServiceProvider; var scopedServices = scope.ServiceProvider;
var dbContext = scopedServices.GetRequiredService<AsbCloudDbContext>(); var dbContext = scopedServices.GetRequiredService<AsbCloudDbContext>();
dbContext.Database.EnsureDeleted();
dbContext.Database.EnsureCreatedAndMigrated(); dbContext.Database.EnsureDeleted();
await FillBaseDatasets(dbContext);
} }
private static async Task FillBaseDatasets(AsbCloudDbContext dbContext) public T GetAuthorizedHttpClient<T>(string uriSuffix)
{
dbContext.AddRange(Data.Defaults.Deposits);
dbContext.AddRange(Data.Defaults.Clusters);
dbContext.AddRange(Data.Defaults.Wells);
dbContext.AddRange(Data.Defaults.RelationsCompanyWell);
dbContext.AddRange(Data.Defaults.Telemetries);
dbContext.AddRange(Data.Defaults.Drillers);
dbContext.AddRange(Data.Defaults.WellOperations);
await dbContext.SaveChangesAsync();
}
public new async Task DisposeAsync()
{ {
using var scope = Services.CreateScope(); var httpClient = GetAuthorizedHttpClient();
var scopedServices = scope.ServiceProvider; if (string.IsNullOrEmpty(uriSuffix))
var dbContext = scopedServices.GetRequiredService<AsbCloudDbContext>(); return RestService.For<T>(httpClient, RefitSettings);
await dbContext.Database.EnsureDeletedAsync();
}
public HttpClient GetAuthorizedHttpClient() if (httpClient.BaseAddress is not null)
{ httpClient.BaseAddress = new Uri(httpClient.BaseAddress, uriSuffix);
var httpClient = CreateClient();
var jwtToken = ApiTokenHelper.GetAdminUserToken();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
return httpClient;
}
public T GetAuthorizedHttpClient<T>(string uriSuffix) return RestService.For<T>(httpClient, RefitSettings);
{ }
var httpClient = GetAuthorizedHttpClient();
if (!string.IsNullOrEmpty(uriSuffix)) private HttpClient GetAuthorizedHttpClient()
if(httpClient.BaseAddress is not null) {
httpClient.BaseAddress = new Uri(httpClient.BaseAddress, uriSuffix); var httpClient = CreateClient();
return RestService.For<T>(httpClient, refitSettings); var jwtToken = ApiTokenHelper.GetAdminUserToken();
} httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
return httpClient;
}
} }

View File

@ -0,0 +1,8 @@
{
"DbConnection": {
"Host": "localhost",
"Port": 5433,
"Username": "postgres",
"Password": "root"
}
}