using Dapper; using KArtSell.Host.Infrastructure; using Npgsql; using Xunit; namespace KArtSell.Integration.Tests; [Collection("Database")] public class KisConnectionPoolTests : IAsyncLifetime { private readonly NpgsqlDataSource _dataSource; public KisConnectionPoolTests(DatabaseFixture fixture) { _dataSource = fixture.DataSource; } public async Task InitializeAsync() { await using var conn = await _dataSource.OpenConnectionAsync(); await conn.ExecuteAsync(""" CREATE SCHEMA IF NOT EXISTS kis; CREATE TABLE IF NOT EXISTS kis.connection_pool_state ( id BIGSERIAL PRIMARY KEY, connection_id UUID NOT NULL UNIQUE, state VARCHAR(50) NOT NULL, priority INT NOT NULL, token_hash VARCHAR(256), expires_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE NOT NULL, released_at TIMESTAMP WITH TIME ZONE, published_at TIMESTAMP WITH TIME ZONE NOT NULL ); CREATE TABLE IF NOT EXISTS kis.token_refresh_log ( id BIGSERIAL PRIMARY KEY, connection_id UUID NOT NULL, refresh_at TIMESTAMP WITH TIME ZONE NOT NULL, status VARCHAR(50) NOT NULL, error_message TEXT, new_token_hash VARCHAR(256), executed_at TIMESTAMP WITH TIME ZONE NOT NULL, published_at TIMESTAMP WITH TIME ZONE NOT NULL ); TRUNCATE kis.connection_pool_state CASCADE; TRUNCATE kis.token_refresh_log CASCADE; """); } public Task DisposeAsync() => Task.CompletedTask; [Fact] public async Task ConnectionPoolSchema_ExistsWithCorrectStructure() { // Verify kis schema and tables exist await using var conn = await _dataSource.OpenConnectionAsync(); var schemaExists = await conn.QueryFirstOrDefaultAsync( "SELECT EXISTS(SELECT 1 FROM information_schema.schemata WHERE schema_name = 'kis')"); Assert.True(schemaExists, "kis schema should exist"); var poolTableExists = await conn.QueryFirstOrDefaultAsync( "SELECT EXISTS(SELECT 1 FROM information_schema.tables WHERE table_schema = 'kis' AND table_name = 'connection_pool_state')"); Assert.True(poolTableExists, "kis.connection_pool_state table should exist"); var tokenLogExists = await conn.QueryFirstOrDefaultAsync( "SELECT EXISTS(SELECT 1 FROM information_schema.tables WHERE table_schema = 'kis' AND table_name = 'token_refresh_log')"); Assert.True(tokenLogExists, "kis.token_refresh_log table should exist"); } [Fact] public async Task ConnectionPoolState_HasRequiredColumns() { await using var conn = await _dataSource.OpenConnectionAsync(); var columnNames = await conn.QueryAsync(""" SELECT column_name FROM information_schema.columns WHERE table_schema = 'kis' AND table_name = 'connection_pool_state' ORDER BY ordinal_position """); var cols = columnNames.ToList(); Assert.Contains("connection_id", cols); Assert.Contains("state", cols); Assert.Contains("priority", cols); Assert.Contains("token_hash", cols); } [Fact] public async Task TokenRefreshLog_HasRequiredColumns() { await using var conn = await _dataSource.OpenConnectionAsync(); var columnNames = await conn.QueryAsync(""" SELECT column_name FROM information_schema.columns WHERE table_schema = 'kis' AND table_name = 'token_refresh_log' ORDER BY ordinal_position """); var cols = columnNames.ToList(); Assert.Contains("connection_id", cols); Assert.Contains("status", cols); Assert.Contains("executed_at", cols); Assert.Contains("published_at", cols); } }