using System.Security.Cryptography;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.AdminUI.Uns;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Uns;
///
/// Verifies — the create-new-script path the inline
/// virtual-tag panel calls when no script is bound yet. A new Script row is inserted with a
/// system-generated SC-… id (mirroring the Script-edit page convention), a blank source, a
/// hash matching that blank source, and the CSharp language; the new id is returned via
/// so the panel can bind the virtual tag to it. Two calls
/// produce two distinct rows with distinct ids.
///
[Trait("Category", "Unit")]
public sealed class UnsTreeServiceCreateScriptTests
{
private static (UnsTreeService Service, string DbName) Fresh()
{
var dbName = $"uns-createscript-{Guid.NewGuid():N}";
return (new UnsTreeService(UnsTreeTestDb.Factory(dbName)), dbName);
}
private static string HashOf(string source) =>
Convert.ToHexStringLower(SHA256.HashData(Encoding.UTF8.GetBytes(source)));
///
/// A create inserts exactly one Script row carrying a non-empty generated id, the expected blank
/// source + matching hash, the CSharp language, and a name; the generated id is echoed back.
///
[Fact]
public async Task CreateScript_inserts_one_row_with_generated_id_and_blank_source()
{
var (service, dbName) = Fresh();
var result = await service.CreateScriptAsync("my new script");
result.Ok.ShouldBeTrue();
result.Error.ShouldBeNull();
result.CreatedId.ShouldNotBeNullOrWhiteSpace();
result.CreatedId!.ShouldStartWith("SC-");
using var db = UnsTreeTestDb.CreateNamed(dbName);
db.Scripts.Count().ShouldBe(1);
var script = db.Scripts.Single();
script.ScriptId.ShouldBe(result.CreatedId);
script.Name.ShouldBe("my new script");
script.SourceCode.ShouldBe("");
script.SourceHash.ShouldBe(HashOf(""));
script.Language.ShouldBe("CSharp");
}
/// A whitespace/empty name falls back to a sensible non-empty default.
[Fact]
public async Task CreateScript_blank_name_uses_a_default_name()
{
var (service, dbName) = Fresh();
var result = await service.CreateScriptAsync(" ");
result.Ok.ShouldBeTrue();
using var db = UnsTreeTestDb.CreateNamed(dbName);
db.Scripts.Single().Name.ShouldNotBeNullOrWhiteSpace();
}
/// Two creates insert two rows with distinct, non-empty ids.
[Fact]
public async Task CreateScript_twice_produces_distinct_ids()
{
var (service, dbName) = Fresh();
var first = await service.CreateScriptAsync("first");
var second = await service.CreateScriptAsync("second");
first.Ok.ShouldBeTrue();
second.Ok.ShouldBeTrue();
first.CreatedId.ShouldNotBe(second.CreatedId);
using var db = UnsTreeTestDb.CreateNamed(dbName);
db.Scripts.Count().ShouldBe(2);
db.Scripts.Select(s => s.ScriptId).Distinct().Count().ShouldBe(2);
}
}