using Akka.Actor; using Akka.TestKit.Xunit2; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; using NSubstitute; using NSubstitute.ExceptionExtensions; using ScadaLink.Commons.Entities.Instances; using ScadaLink.Commons.Entities.Templates; using ScadaLink.Commons.Interfaces.Repositories; using ScadaLink.Commons.Interfaces.Services; using ScadaLink.Commons.Messages.Management; using ScadaLink.Commons.Types; using ScadaLink.ManagementService; using ScadaLink.TemplateEngine.Services; namespace ScadaLink.ManagementService.Tests; public class ManagementActorTests : TestKit, IDisposable { private readonly ITemplateEngineRepository _templateRepo; private readonly IAuditService _auditService; private readonly ServiceCollection _services; public ManagementActorTests() { _templateRepo = Substitute.For(); _auditService = Substitute.For(); _services = new ServiceCollection(); _services.AddScoped(_ => _templateRepo); _services.AddScoped(_ => _auditService); _services.AddScoped(); } private IActorRef CreateActor() { var sp = _services.BuildServiceProvider(); return Sys.ActorOf(Props.Create(() => new ManagementActor( sp, NullLogger.Instance))); } private static ManagementEnvelope Envelope(object command, params string[] roles) => new(new AuthenticatedUser("testuser", "Test User", roles, Array.Empty()), command, Guid.NewGuid().ToString("N")); void IDisposable.Dispose() { Shutdown(); } // ======================================================================== // 1. Authorization test -- admin command with wrong role // ======================================================================== [Fact] public void CreateSiteCommand_WithDesignRole_ReturnsUnauthorized() { var actor = CreateActor(); var envelope = Envelope(new CreateSiteCommand("Site1", "SITE1", "Desc"), "Design"); actor.Tell(envelope); var response = ExpectMsg(TimeSpan.FromSeconds(5)); Assert.Contains("Admin", response.Message); Assert.Equal(envelope.CorrelationId, response.CorrelationId); } [Fact] public void CreateSiteCommand_WithNoRoles_ReturnsUnauthorized() { var actor = CreateActor(); var envelope = Envelope(new CreateSiteCommand("Site1", "SITE1", null)); actor.Tell(envelope); var response = ExpectMsg(TimeSpan.FromSeconds(5)); Assert.Contains("Admin", response.Message); } [Fact] public void DeploymentCommand_WithDesignRole_ReturnsUnauthorized() { var actor = CreateActor(); var envelope = Envelope(new CreateInstanceCommand("Inst1", 1, 1), "Design"); actor.Tell(envelope); var response = ExpectMsg(TimeSpan.FromSeconds(5)); Assert.Contains("Deployment", response.Message); } // ======================================================================== // 2. Read-only query passes without special role // ======================================================================== [Fact] public void ListTemplatesCommand_WithNoRoles_ReturnsSuccess() { var templates = new List