64 lines
3.0 KiB
C#
64 lines
3.0 KiB
C#
using Akka.Actor;
|
|
using Akka.TestKit.Xunit2;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using NSubstitute;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Templates;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.ManagementService.Tests;
|
|
|
|
/// <summary>
|
|
/// Review 2026-10-21 (lane F follow-up to 01/SR-C1): a native alarm source's name becomes
|
|
/// part of the site actor name <c>native-alarm-{canonical}</c>. Template scripts, alarms and
|
|
/// composition slots are validated by <c>TemplateService</c>, but native-source CRUD is
|
|
/// repository-direct in the ManagementActor, so it must apply <c>ActorNameRules</c> itself.
|
|
/// </summary>
|
|
public class NativeAlarmSourceNameValidationTests : TestKit
|
|
{
|
|
private readonly ITemplateEngineRepository _repo = Substitute.For<ITemplateEngineRepository>();
|
|
private readonly ServiceCollection _services = new ServiceCollection().AddTestConfigurationTransaction();
|
|
|
|
/// <summary>Initializes the harness.</summary>
|
|
public NativeAlarmSourceNameValidationTests()
|
|
{
|
|
_services.AddScoped(_ => _repo);
|
|
_repo.GetTemplateNativeAlarmSourceByIdAsync(4, Arg.Any<CancellationToken>())
|
|
.Returns(new TemplateNativeAlarmSource("Pressure") { Id = 4, TemplateId = 1 });
|
|
}
|
|
|
|
private IActorRef CreateActor() =>
|
|
Sys.ActorOf(Props.Create(() => new ManagementActor(
|
|
_services.BuildServiceProvider(), NullLogger<ManagementActor>.Instance)));
|
|
|
|
private static ManagementEnvelope Designer(object command) =>
|
|
new(new AuthenticatedUser("d", "D", new[] { "Designer" }, Array.Empty<string>()),
|
|
command, Guid.NewGuid().ToString("N"));
|
|
|
|
/// <summary>Adding a source whose name is not a legal actor name is rejected before any write.</summary>
|
|
[Theory]
|
|
[InlineData("Tank Pressure")]
|
|
[InlineData("$system")]
|
|
[InlineData("a/b")]
|
|
public void Add_InvalidActorName_IsRejected(string name)
|
|
{
|
|
CreateActor().Tell(Designer(new AddTemplateNativeAlarmSourceCommand(1, name, "Opc", "ns=2;s=T01", null, null, false)));
|
|
|
|
var error = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
|
Assert.Contains("Native alarm source name is invalid", error.Error);
|
|
_repo.DidNotReceive().AddTemplateNativeAlarmSourceAsync(Arg.Any<TemplateNativeAlarmSource>(), Arg.Any<CancellationToken>());
|
|
}
|
|
|
|
/// <summary>Renaming a source to an illegal actor name is rejected before any write.</summary>
|
|
[Fact]
|
|
public void Update_RenameToInvalidActorName_IsRejected()
|
|
{
|
|
CreateActor().Tell(Designer(new UpdateTemplateNativeAlarmSourceCommand(4, "Tank Pressure", "Opc", "ns=2;s=T01", null, null, false)));
|
|
|
|
var error = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
|
Assert.Contains("Native alarm source name is invalid", error.Error);
|
|
_repo.DidNotReceive().UpdateTemplateNativeAlarmSourceAsync(Arg.Any<TemplateNativeAlarmSource>(), Arg.Any<CancellationToken>());
|
|
}
|
|
}
|