using Microsoft.Data.Sqlite;
using Shouldly;
using Xunit;
namespace ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.Tests;
///
/// Verifies creates its table and is idempotent —
/// the DDL depends on nothing but a , so a bare in-memory
/// connection is a faithful harness (no zb_hlc_next() UDF is involved in CREATE TABLE).
///
[Trait("Category", "Unit")]
public sealed class AlarmConditionStateSchemaTests
{
private static SqliteConnection OpenInMemory()
{
var connection = new SqliteConnection("Data Source=:memory:");
connection.Open();
return connection;
}
/// A single Apply creates the table.
[Fact]
public void Apply_creates_the_state_table()
{
using var connection = OpenInMemory();
AlarmConditionStateSchema.Apply(connection);
using var cmd = connection.CreateCommand();
cmd.CommandText =
"SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = @Name";
cmd.Parameters.AddWithValue("@Name", AlarmConditionStateSchema.StateTable);
((long)cmd.ExecuteScalar()!).ShouldBe(1);
}
/// Apply also creates the append-only comment table, keyed by alarm id + ordinal.
[Fact]
public void Apply_creates_the_comment_table_with_a_composite_key()
{
using var connection = OpenInMemory();
AlarmConditionStateSchema.Apply(connection);
using var cmd = connection.CreateCommand();
cmd.CommandText = "SELECT name FROM pragma_table_info(@Name) WHERE pk > 0 ORDER BY pk";
cmd.Parameters.AddWithValue("@Name", AlarmConditionStateSchema.CommentsTable);
var pk = new List();
using (var reader = cmd.ExecuteReader())
while (reader.Read()) pk.Add(reader.GetString(0));
pk.ShouldBe(["scripted_alarm_id", "seq"]);
}
/// Applying twice on the same connection does not throw (CREATE TABLE IF NOT EXISTS).
[Fact]
public void Apply_is_idempotent()
{
using var connection = OpenInMemory();
AlarmConditionStateSchema.Apply(connection);
Should.NotThrow(() => AlarmConditionStateSchema.Apply(connection));
}
}