123 lines
6.2 KiB
C#
123 lines
6.2 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
using Microsoft.EntityFrameworkCore.Migrations;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Tiku.Infrastructure.Persistence;
|
|
using Tiku.IntegrationTests.Api;
|
|
|
|
namespace Tiku.IntegrationTests;
|
|
|
|
public sealed class MigrationExecutionTests
|
|
{
|
|
[Fact]
|
|
public async Task Api_test_database_uses_postgresql_and_applies_every_migration()
|
|
{
|
|
await using var factory = new ApiTestFactory();
|
|
using var scope = factory.Services.CreateScope();
|
|
var dbContext = scope.ServiceProvider.GetRequiredService<TikuDbContext>();
|
|
|
|
var appliedMigrations = await dbContext.Database.GetAppliedMigrationsAsync();
|
|
var expectedMigrations = dbContext.Database.GetMigrations();
|
|
|
|
Assert.Equal("Npgsql.EntityFrameworkCore.PostgreSQL", dbContext.Database.ProviderName);
|
|
Assert.Equal(expectedMigrations, appliedMigrations);
|
|
Assert.NotEmpty(appliedMigrations);
|
|
Assert.True(await dbContext.Database.CanConnectAsync());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Migration_script_contains_database_guard_triggers()
|
|
{
|
|
await using var factory = new ApiTestFactory();
|
|
using var scope = factory.Services.CreateScope();
|
|
var dbContext = scope.ServiceProvider.GetRequiredService<TikuDbContext>();
|
|
var migrator = dbContext.GetService<IMigrator>();
|
|
|
|
var script = migrator.GenerateScript();
|
|
|
|
Assert.Contains("drop trigger if exists trg_tenant_question_references_platform_or_self_owner", script);
|
|
Assert.Contains("create or replace function tiku_guard_tenant_question_reference()", script);
|
|
Assert.Contains("create trigger trg_tenant_question_references_platform_or_self_owner", script);
|
|
Assert.Contains("drop trigger if exists trg_taxonomy_nodes_parent_platform_or_self_owner", script);
|
|
Assert.Contains("create or replace function tiku_guard_taxonomy_parent_owner()", script);
|
|
Assert.Contains("create trigger trg_taxonomy_nodes_parent_platform_or_self_owner", script);
|
|
Assert.Contains("drop trigger if exists trg_saas_offering_versions_published_immutable", script);
|
|
Assert.Contains("create or replace function tiku_guard_saas_offering_version_immutable()", script);
|
|
Assert.Contains("create trigger trg_saas_offering_versions_published_immutable", script);
|
|
Assert.Contains("create or replace function tiku_guard_saas_offering_version_child_immutable()", script);
|
|
Assert.Contains("create trigger trg_saas_offering_version_features_published_immutable", script);
|
|
Assert.Contains("create trigger trg_saas_offering_version_limits_published_immutable", script);
|
|
Assert.Contains("create trigger trg_tenant_saas_subscriptions_base_plan", script);
|
|
Assert.Contains("create trigger trg_tenant_saas_subscription_items_offering_type", script);
|
|
Assert.Contains("create or replace function tiku_guard_saas_subscription_offering_type()", script);
|
|
Assert.Contains("CREATE OR REPLACE FUNCTION tiku_bump_tenant_authorization_version()", script);
|
|
Assert.Contains("CREATE OR REPLACE FUNCTION tiku_bump_platform_authorization_version()", script);
|
|
Assert.Contains("CREATE TRIGGER trg_backend_permissions_authorization_version", script);
|
|
Assert.Contains("CREATE INDEX IF NOT EXISTS ix_scoreline_records_field_values_jsonb_path", script);
|
|
Assert.Contains("CREATE INDEX IF NOT EXISTS ix_scoreline_records_school_name_trgm", script);
|
|
Assert.Contains("CREATE INDEX IF NOT EXISTS ix_background_jobs_pending_due", script);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Migrated_database_contains_required_non_model_objects()
|
|
{
|
|
await using var factory = new ApiTestFactory();
|
|
using var scope = factory.Services.CreateScope();
|
|
var dbContext = scope.ServiceProvider.GetRequiredService<TikuDbContext>();
|
|
|
|
await dbContext.Database.OpenConnectionAsync();
|
|
try
|
|
{
|
|
Assert.Equal(3L, await CountAsync("""
|
|
SELECT count(*)
|
|
FROM pg_proc
|
|
WHERE proname IN (
|
|
'tiku_bump_tenant_authorization_version',
|
|
'tiku_bump_platform_authorization_version',
|
|
'tiku_bump_all_authorization_versions')
|
|
"""));
|
|
Assert.Equal(7L, await CountAsync("""
|
|
SELECT count(*)
|
|
FROM pg_trigger
|
|
WHERE NOT tgisinternal
|
|
AND tgname IN (
|
|
'trg_tenant_backend_roles_authorization_version',
|
|
'trg_tenant_backend_role_permissions_authorization_version',
|
|
'trg_tenant_backend_user_roles_authorization_version',
|
|
'trg_platform_backend_roles_authorization_version',
|
|
'trg_platform_backend_role_permissions_authorization_version',
|
|
'trg_platform_backend_user_roles_authorization_version',
|
|
'trg_backend_permissions_authorization_version')
|
|
"""));
|
|
Assert.Equal(6L, await CountAsync("""
|
|
SELECT count(*)
|
|
FROM pg_indexes
|
|
WHERE schemaname = current_schema()
|
|
AND indexname IN (
|
|
'ix_scoreline_records_tenant_id_year_school_name_major_name_id',
|
|
'ix_scoreline_records_field_values_jsonb_path',
|
|
'ix_scoreline_records_school_name_trgm',
|
|
'ix_scoreline_records_major_name_trgm',
|
|
'ix_background_jobs_pending_due',
|
|
'ix_background_jobs_processing_lease')
|
|
"""));
|
|
Assert.Equal(1L, await CountAsync("""
|
|
SELECT count(*)
|
|
FROM authorization_scope_versions
|
|
WHERE realm = 'platform' AND tenant_id IS NULL
|
|
"""));
|
|
}
|
|
finally
|
|
{
|
|
await dbContext.Database.CloseConnectionAsync();
|
|
}
|
|
|
|
async Task<long> CountAsync(string sql)
|
|
{
|
|
await using var command = dbContext.Database.GetDbConnection().CreateCommand();
|
|
command.CommandText = sql;
|
|
return Convert.ToInt64(await command.ExecuteScalarAsync());
|
|
}
|
|
}
|
|
}
|