using System; using System.Collections.Generic; using System.Data; using System.IO; using Junction.Domain; using Junction.Persistence; using Xunit; namespace Junction.Tests.Unit { /// /// Integration-style tests against a REAL SQLite file. Proves the native e_sqlite3 /// library loads and runs on the Linux net8.0 test host (relevant to the net48 story). /// public sealed class SqliteSchemaTests : IDisposable { private readonly string _dbPath; private readonly string _connectionString; public SqliteSchemaTests() { _dbPath = Path.Combine(Path.GetTempPath(), "junction_test_" + Guid.NewGuid().ToString("N") + ".db"); _connectionString = "Data Source=" + _dbPath; } public void Dispose() { try { if (File.Exists(_dbPath)) { File.Delete(_dbPath); } } catch { // best-effort cleanup } } [Fact] public void ConnectionFactory_OpensUsableConnection() { var factory = new SqliteConnectionFactory(_connectionString); using (IDbConnection connection = factory.CreateOpenConnection()) { Assert.Equal(ConnectionState.Open, connection.State); using (var cmd = connection.CreateCommand()) { cmd.CommandText = "SELECT 1;"; var value = Convert.ToInt64(cmd.ExecuteScalar()); Assert.Equal(1L, value); } } } [Fact] public void EnsureCreated_CreatesAllThreeTables() { var factory = new SqliteConnectionFactory(_connectionString); Result result = SqliteSchema.EnsureCreated(factory); Assert.True(result.IsSuccess, DescribeErrors(result)); var tables = QueryTableNames(); Assert.Contains("machines", tables); Assert.Contains("latest_snapshots", tables); Assert.Contains("snapshot_items", tables); } [Fact] public void EnsureCreated_IsIdempotent() { var factory = new SqliteConnectionFactory(_connectionString); Result first = SqliteSchema.EnsureCreated(factory); Result second = SqliteSchema.EnsureCreated(factory); Assert.True(first.IsSuccess, DescribeErrors(first)); Assert.True(second.IsSuccess, DescribeErrors(second)); var tables = QueryTableNames(); Assert.Contains("machines", tables); Assert.Contains("latest_snapshots", tables); Assert.Contains("snapshot_items", tables); } [Fact] public void EnsureCreated_OnOpenConnection_Works() { var factory = new SqliteConnectionFactory(_connectionString); using (IDbConnection connection = factory.CreateOpenConnection()) { Result result = SqliteSchema.EnsureCreated(connection); Assert.True(result.IsSuccess, DescribeErrors(result)); } } private List QueryTableNames() { var names = new List(); var factory = new SqliteConnectionFactory(_connectionString); using (IDbConnection connection = factory.CreateOpenConnection()) using (var cmd = connection.CreateCommand()) { cmd.CommandText = "SELECT name FROM sqlite_master WHERE type = 'table';"; using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { names.Add(reader.GetString(0)); } } } return names; } private static string DescribeErrors(Result result) { if (result.IsSuccess) { return ""; } return string.Join("; ", System.Linq.Enumerable.Select(result.Errors, e => e.ToString())); } } }