Files
tiku-backend.net/Tiku.IntegrationTests/Api/ApiTestFactory.cs

136 lines
4.7 KiB
C#

using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Npgsql;
using Tiku.Application.Commerce;
using Tiku.Application.Auth;
using Tiku.Application.Growth;
using Tiku.Application.Storage;
using Tiku.Domain.Identity;
using Tiku.Domain.QuestionBanks;
using Tiku.Domain.Tenancy;
using Tiku.IntegrationTests.Infrastructure;
using Tiku.Infrastructure.Persistence;
namespace Tiku.IntegrationTests.Api;
public sealed class ApiTestFactory(
IWechatOAuthClient? wechatOAuthClient = null,
IObjectStorageService? objectStorageService = null,
IReferralQrcodeGenerator? referralQrcodeGenerator = null,
IPaymentProviderGateway? paymentProviderGateway = null) : WebApplicationFactory<Program>
{
private readonly PostgresTestDatabase database = PostgresTestDatabase.Create();
protected override void ConfigureWebHost(Microsoft.AspNetCore.Hosting.IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
foreach (var descriptor in services
.Where(descriptor =>
descriptor.ServiceType == typeof(NpgsqlDataSource) ||
descriptor.ServiceType == typeof(DbContextOptions<TikuDbContext>) ||
descriptor.ServiceType.FullName?.Contains(nameof(TikuDbContext), StringComparison.Ordinal) == true)
.ToArray())
{
services.Remove(descriptor);
}
services.AddSingleton(_ => NpgsqlDataSource.Create(database.ConnectionString));
services.AddDbContextPool<TikuDbContext>((serviceProvider, options) =>
{
var dataSource = serviceProvider.GetRequiredService<NpgsqlDataSource>();
options.UseNpgsql(dataSource, npgsql =>
npgsql.MigrationsAssembly(typeof(TikuDbContext).Assembly.FullName));
});
if (wechatOAuthClient is not null)
{
services.AddSingleton(wechatOAuthClient);
}
if (objectStorageService is not null)
{
services.AddSingleton(objectStorageService);
}
if (referralQrcodeGenerator is not null)
{
services.AddSingleton(referralQrcodeGenerator);
}
if (paymentProviderGateway is not null)
{
services.AddSingleton(paymentProviderGateway);
}
});
}
public async Task SeedAsync(params object[] entities)
{
using var scope = Services.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<TikuDbContext>();
dbContext.AddRange(entities);
await dbContext.SaveChangesAsync();
}
public async Task SeedQuestionWithVersionAsync(Question question, QuestionVersion version)
{
question.CurrentVersionId = null;
await SeedAsync(question);
await SeedAsync(version);
using var scope = Services.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<TikuDbContext>();
var persistedQuestion = await dbContext.Questions.SingleAsync(item =>
item.TenantId == question.TenantId && item.Id == question.Id);
persistedQuestion.CurrentVersionId = version.Id;
await dbContext.SaveChangesAsync();
}
public async Task<Guid> SeedActiveSessionAsync(
Guid userId,
Guid? tenantId = null,
string tokenHash = "integration-test-token-hash")
{
var resolvedTenantId = tenantId ?? Guid.NewGuid();
await SeedAsync(
new Tenant
{
Id = resolvedTenantId,
Slug = resolvedTenantId.ToString("N"),
Name = "Test Tenant"
},
new User
{
Id = userId,
Phone = "13800000000"
},
new AuthSession
{
Id = Guid.NewGuid(),
TenantId = resolvedTenantId,
UserId = userId,
TokenHash = tokenHash,
Provider = "test",
ExpiresAt = DateTimeOffset.UtcNow.AddHours(1)
});
using var scope = Services.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<TikuDbContext>();
return await dbContext.AuthSessions
.Where(session => session.UserId == userId)
.Select(session => session.Id)
.SingleAsync();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
database.Dispose();
}
}
}