using Moq;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Templates;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Templates;
namespace ZB.MOM.WW.ScadaBridge.TemplateEngine.Tests;
///
/// Gitea #66: member add/update now asks the repository for a template's analysis closure
/// rather than the whole analysis graph. Test classes keep seeding the whole graph through
/// GetAllTemplatesForAnalysisAsync; this wires GetTemplateAnalysisClosureAsync
/// to serve the real closure walk over that seeded graph, so every existing scenario runs the
/// service against the reduced set — the same set the production repository returns.
///
internal static class AnalysisClosureMock
{
/// Wires the closure method to filter whatever the full-graph setup returns.
/// The repository mock.
/// Optional sink recording each requested closure root.
public static void ServeClosureFromFullGraph(
this Mock repoMock,
List? closureRequests = null)
{
repoMock
.Setup(r => r.GetTemplateAnalysisClosureAsync(It.IsAny(), It.IsAny()))
.Returns((int templateId, CancellationToken ct) =>
{
closureRequests?.Add(templateId);
return TemplateAnalysisClosure.CollectAsync(
templateId,
async (ids, token) =>
{
var all = await repoMock.Object.GetAllTemplatesForAnalysisAsync(token)
?? Array.Empty();
return all.Where(t => ids.Contains(t.Id)).ToList();
},
ct);
});
}
///
/// Gitea #86: the descendant reconcile now asks for the reconcile closure (derived subtree +
/// the template's chain) instead of GetAllTemplatesAsync. Wires it to run the real
/// closure walk over whatever the full tracked-graph setup returns, so every existing
/// propagation scenario exercises the service against the reduced set.
///
/// The repository mock.
/// Optional sink recording each requested closure root.
public static void ServeReconcileClosureFromFullGraph(
this Mock repoMock,
List? closureRequests = null)
{
async Task> All(CancellationToken token) =>
await repoMock.Object.GetAllTemplatesAsync(token) ?? Array.Empty();
repoMock
.Setup(r => r.GetTemplateReconcileClosureAsync(It.IsAny(), It.IsAny()))
.Returns((int templateId, CancellationToken ct) =>
{
closureRequests?.Add(templateId);
return TemplateReconcileClosure.CollectAsync(
templateId,
async (parentIds, token) => (await All(token))
.Where(t => t.ParentTemplateId is int p && parentIds.Contains(p)).ToList(),
async (ids, token) => (await All(token)).Where(t => ids.Contains(t.Id)).ToList(),
ct);
});
}
}