feat(templates): GetTemplateStubsAsync untracked identity/edge projection
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Instances;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Scripts;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Templates;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Templates;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
|
||||
|
||||
@@ -55,6 +56,12 @@ public interface ITemplateEngineRepository
|
||||
/// <returns>A task that resolves to a read-only list of all templates without script bodies.</returns>
|
||||
Task<IReadOnlyList<Template>> GetAllTemplatesForAnalysisAsync(CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// Returns an untracked identity/edge projection of every template (no children), ordered by name.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that resolves to a read-only list of template stubs.</returns>
|
||||
Task<IReadOnlyList<TemplateStub>> GetTemplateStubsAsync(CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// Database-side paged listing of templates as row summaries (child
|
||||
/// collections reduced to counts, no script bodies). Backs the
|
||||
/// <c>ListTemplates</c> management command, which previously materialised
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Templates;
|
||||
|
||||
/// <summary>
|
||||
/// Lightweight template identity/edge projection (no attributes, alarms, scripts or compositions)
|
||||
/// for callers that only need names and the inheritance/folder/ownership edges.
|
||||
/// </summary>
|
||||
/// <param name="Id">Template ID.</param>
|
||||
/// <param name="Name">Template name.</param>
|
||||
/// <param name="ParentTemplateId">Base template, if any.</param>
|
||||
/// <param name="FolderId">Containing folder, if any.</param>
|
||||
/// <param name="IsDerived">True for auto-derived composition templates.</param>
|
||||
/// <param name="OwnerCompositionId">Owning composition row for derived templates.</param>
|
||||
public sealed record TemplateStub(
|
||||
int Id,
|
||||
string Name,
|
||||
int? ParentTemplateId,
|
||||
int? FolderId,
|
||||
bool IsDerived,
|
||||
int? OwnerCompositionId);
|
||||
+10
@@ -90,6 +90,16 @@ public class TemplateEngineRepository : ITemplateEngineRepository
|
||||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<TemplateStub>> GetTemplateStubsAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _context.Templates
|
||||
.AsNoTracking()
|
||||
.OrderBy(t => t.Name)
|
||||
.Select(t => new TemplateStub(t.Id, t.Name, t.ParentTemplateId, t.FolderId, t.IsDerived, t.OwnerCompositionId))
|
||||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
// Two deliberate departures from <see cref="GetAllTemplatesAsync"/>:
|
||||
// <list type="number">
|
||||
|
||||
+21
@@ -31,6 +31,27 @@ public class TemplateEngineRepositoryTests : IDisposable
|
||||
_context.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>Verifies the stub projection carries identity and edges and leaves nothing tracked.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task GetTemplateStubs_ProjectsEdgesUntrackedOrderedByName()
|
||||
{
|
||||
var baseT = new Template("Base");
|
||||
_context.Templates.Add(baseT);
|
||||
await _context.SaveChangesAsync();
|
||||
_context.Templates.Add(new Template("Alpha") { ParentTemplateId = baseT.Id });
|
||||
await _context.SaveChangesAsync();
|
||||
_context.ChangeTracker.Clear();
|
||||
|
||||
var stubs = await _repository.GetTemplateStubsAsync();
|
||||
|
||||
Assert.Equal(new[] { "Alpha", "Base" }, stubs.Select(s => s.Name));
|
||||
Assert.Equal(baseT.Id, stubs[0].ParentTemplateId);
|
||||
Assert.Null(stubs[1].ParentTemplateId);
|
||||
Assert.False(stubs[0].IsDerived);
|
||||
Assert.Empty(_context.ChangeTracker.Entries());
|
||||
}
|
||||
|
||||
/// <summary>Verifies that the topology page is bounded, filtered and returned untracked.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user