using Akka.Actor;
using Akka.TestKit.Xunit2;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NSubstitute;
using NSubstitute.ExceptionExtensions;
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;
///
/// Gitea #89: the read-only resolves from the
/// template's own inheritance chain, read untracked, instead of loading the whole tracked library.
///
public class ResolvedTemplateMembersReadTests : TestKit
{
private readonly ITemplateEngineRepository _repo = Substitute.For();
private readonly ServiceCollection _services = new ServiceCollection().AddTestConfigurationTransaction();
/// Initializes the harness: a Base → Child chain; the whole-library read throws.
public ResolvedTemplateMembersReadTests()
{
_services.AddScoped(_ => _repo);
var baseT = new Template("Base") { Id = 7 };
baseT.Attributes.Add(new TemplateAttribute("Speed") { Id = 70, TemplateId = 7, Value = "42" });
var child = new Template("Child") { Id = 8, ParentTemplateId = 7, IsDerived = true };
_repo.GetAllTemplatesAsync(Arg.Any())
.ThrowsAsync(new InvalidOperationException("resolved-members loaded the whole library"));
_repo.GetTemplateChainAsync(8, false, Arg.Any())
.Returns(new List { child, baseT });
}
private IActorRef CreateActor() =>
Sys.ActorOf(Props.Create(() => new ManagementActor(
_services.BuildServiceProvider(), NullLogger.Instance)));
private static ManagementEnvelope Viewer(object command) =>
new(new AuthenticatedUser("v", "V", Array.Empty(), Array.Empty()),
command, Guid.NewGuid().ToString("N"));
/// The resolved set comes from the untracked chain read; the library is never loaded.
/// A task that represents the asynchronous operation.
[Fact]
public async Task ResolvedMembers_ResolveFromUntrackedChain_NotWholeLibrary()
{
CreateActor().Tell(Viewer(new GetResolvedTemplateMembersCommand(8)));
var success = ExpectMsg(TimeSpan.FromSeconds(5));
Assert.Contains("\"Speed\"", success.JsonData, StringComparison.OrdinalIgnoreCase);
Assert.Contains("42", success.JsonData, StringComparison.Ordinal);
await _repo.Received(1).GetTemplateChainAsync(8, false, Arg.Any());
await _repo.DidNotReceive().GetAllTemplatesAsync(Arg.Any());
}
}