using GB5Shared.DTO.Framework.Login; using GB5Shared.EventLogPublish; using Microsoft.Extensions.Logging.Abstractions; using Moq; using SwBLL.ChangeRequest; using SwBLL.ClientDatabase; using SwBLL.DbServer; using SwBLL.DdlScript; using SwBLL.Provisioning; using SwBLL.UserResourceRole; using SwDAL.CustomCode.ChangeRequest; using SwDAL.DTO.ChangeRequest; using SwDAL.DTO.DdlScript; using SwDAL.Enums; using Xunit; namespace SwTests; /// /// Covers ChangeRequestBLL.GetById's real-time DDL progress enrichment (tracker §37 Decision 2) /// — ScriptsDone/ScriptsTotal are only ever computed for Category == ClientProvisioning, since /// that's the only category anyone polls for live provisioning status. /// public class ChangeRequestBLLProgressTests { private static (ChangeRequestBLL Svc, Mock Dal, Mock DdlScriptBLL) BuildService() { var dal = new Mock(); var ddlScriptBLL = new Mock(); var eventLogPublish = new EventLogPublish(null!, NullLogger.Instance); var svc = new ChangeRequestBLL( dal.Object, new Mock().Object, new Mock().Object, new Mock().Object, ddlScriptBLL.Object, new Mock().Object, new Mock().Object, eventLogPublish, NullLogger.Instance); return (svc, dal, ddlScriptBLL); } private static LoginDTO TestLogin() => new() { ClientId = 1, UserId = -1 }; [Fact] public async Task Test_GetById_ClientProvisioningCategory_EnrichesScriptsDoneTotal() { var (svc, dal, ddlScriptBLL) = BuildService(); var cr = new ChangeRequestDTO { ChangeRequestId = 100, ClientDatabaseId = 5, Category = ChangeRequestCategory.ClientProvisioning }; dal.Setup(d => d.GetById(100, It.IsAny(), It.IsAny())).ReturnsAsync(cr); dal.Setup(d => d.GetLinkedApprovedDdlScripts(100, It.IsAny(), It.IsAny())) .ReturnsAsync(new List { new() { DdlScriptId = 1, SqlScript = "S1" }, new() { DdlScriptId = 2, SqlScript = "S2" }, new() { DdlScriptId = 3, SqlScript = "S3" }, }); ddlScriptBLL.Setup(d => d.CountExecutedScriptsAsync(5, It.IsAny>(), It.IsAny(), It.IsAny())) .ReturnsAsync(2); var result = await svc.GetById(100, TestLogin(), CancellationToken.None); Assert.Equal(3, result!.ScriptsTotal); Assert.Equal(2, result.ScriptsDone); ddlScriptBLL.Verify(d => d.CountExecutedScriptsAsync(5, It.Is>(ids => ids.SequenceEqual(new[] { 1, 2, 3 })), It.IsAny(), It.IsAny()), Times.Once); } [Fact] public async Task Test_GetById_NonClientProvisioningCategory_DoesNotEnrich_NeverCallsDdlScriptBLL() { var (svc, dal, ddlScriptBLL) = BuildService(); var cr = new ChangeRequestDTO { ChangeRequestId = 101, ClientDatabaseId = 5, Category = ChangeRequestCategory.SchemaChange }; dal.Setup(d => d.GetById(101, It.IsAny(), It.IsAny())).ReturnsAsync(cr); var result = await svc.GetById(101, TestLogin(), CancellationToken.None); Assert.Null(result!.ScriptsTotal); Assert.Null(result.ScriptsDone); dal.Verify(d => d.GetLinkedApprovedDdlScripts(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); ddlScriptBLL.Verify(d => d.CountExecutedScriptsAsync( It.IsAny(), It.IsAny>(), It.IsAny(), It.IsAny()), Times.Never); } [Fact] public async Task Test_GetById_ClientProvisioningCategory_NoLinkedScripts_ReportsZeroZero_NoCountCall() { var (svc, dal, ddlScriptBLL) = BuildService(); var cr = new ChangeRequestDTO { ChangeRequestId = 102, ClientDatabaseId = 5, Category = ChangeRequestCategory.ClientProvisioning }; dal.Setup(d => d.GetById(102, It.IsAny(), It.IsAny())).ReturnsAsync(cr); dal.Setup(d => d.GetLinkedApprovedDdlScripts(102, It.IsAny(), It.IsAny())) .ReturnsAsync(new List()); var result = await svc.GetById(102, TestLogin(), CancellationToken.None); Assert.Equal(0, result!.ScriptsTotal); Assert.Equal(0, result.ScriptsDone); ddlScriptBLL.Verify(d => d.CountExecutedScriptsAsync( It.IsAny(), It.IsAny>(), It.IsAny(), It.IsAny()), Times.Never); } }