test(adminui): cover divergent-prefix {{equip}} rejection; use EquipToken constant in message
This commit is contained in:
@@ -375,7 +375,8 @@ public interface IUnsTreeService
|
|||||||
/// <param name="equipmentId">The owning equipment.</param>
|
/// <param name="equipmentId">The owning equipment.</param>
|
||||||
/// <param name="input">The operator-editable virtual-tag fields.</param>
|
/// <param name="input">The operator-editable virtual-tag fields.</param>
|
||||||
/// <param name="ct">A token to cancel the operation.</param>
|
/// <param name="ct">A token to cancel the operation.</param>
|
||||||
/// <returns>Success, or one of the guard failures.</returns>
|
/// <returns>Success, or one of the guard failures; or if the chosen script uses the <c>{{equip}}</c>
|
||||||
|
/// token but the equipment has no derivable single tag base.</returns>
|
||||||
Task<UnsMutationResult> CreateVirtualTagAsync(string equipmentId, VirtualTagInput input, CancellationToken ct = default);
|
Task<UnsMutationResult> CreateVirtualTagAsync(string equipmentId, VirtualTagInput input, CancellationToken ct = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -389,7 +390,8 @@ public interface IUnsTreeService
|
|||||||
/// <param name="input">The new operator-editable virtual-tag fields.</param>
|
/// <param name="input">The new operator-editable virtual-tag fields.</param>
|
||||||
/// <param name="rowVersion">The concurrency token the caller last read.</param>
|
/// <param name="rowVersion">The concurrency token the caller last read.</param>
|
||||||
/// <param name="ct">A token to cancel the operation.</param>
|
/// <param name="ct">A token to cancel the operation.</param>
|
||||||
/// <returns>Success, a missing-row failure, a guard failure, or a concurrency failure.</returns>
|
/// <returns>Success, a missing-row failure, a guard failure, or a concurrency failure; or if the
|
||||||
|
/// chosen script uses the <c>{{equip}}</c> token but the equipment has no derivable single tag base.</returns>
|
||||||
Task<UnsMutationResult> UpdateVirtualTagAsync(string virtualTagId, VirtualTagInput input, byte[] rowVersion, CancellationToken ct = default);
|
Task<UnsMutationResult> UpdateVirtualTagAsync(string virtualTagId, VirtualTagInput input, byte[] rowVersion, CancellationToken ct = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -908,12 +908,10 @@ public sealed class UnsTreeService(IDbContextFactory<OtOpcUaConfigDbContext> dbF
|
|||||||
var fullNames = configs.Select(TagConfigFullName.Extract);
|
var fullNames = configs.Select(TagConfigFullName.Extract);
|
||||||
if (EquipmentScriptPaths.DeriveEquipmentBase(fullNames) is null)
|
if (EquipmentScriptPaths.DeriveEquipmentBase(fullNames) is null)
|
||||||
{
|
{
|
||||||
// NOTE: literal {{equip}} must survive — in a C# interpolated string `{{`/`}}`
|
|
||||||
// collapse to single braces, so keep the token text in a NON-interpolated segment.
|
|
||||||
return new UnsMutationResult(false,
|
return new UnsMutationResult(false,
|
||||||
$"Equipment '{equipmentId}' has no single tag base, so the "
|
$"Equipment '{equipmentId}' has no single tag base, so the "
|
||||||
+ "{{equip}} token can't be resolved. Add at least one driver tag under this "
|
+ $"{EquipmentScriptPaths.EquipToken} token can't be resolved. Add at least one driver tag under this "
|
||||||
+ "equipment (all sharing one object prefix), or remove {{equip}} from the script.");
|
+ $"equipment (all sharing one object prefix), or remove {EquipmentScriptPaths.EquipToken} from the script.");
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+35
@@ -138,6 +138,41 @@ public sealed class VirtualTagEquipTokenValidationTests
|
|||||||
result.Error.ShouldBeNull();
|
result.Error.ShouldBeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// {{equip}} script + TWO driver tags whose FullNames have DIFFERENT object prefixes
|
||||||
|
/// (no single base can be derived) → create rejected, error names equipment + token.
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public async Task Create_equip_token_with_divergent_prefixes_rejected()
|
||||||
|
{
|
||||||
|
var (service, dbName) = Fresh();
|
||||||
|
Seed(dbName, EquipBaseScript, tagFullName: "TestMachine_001.X");
|
||||||
|
using (var db = UnsTreeTestDb.CreateNamed(dbName))
|
||||||
|
{
|
||||||
|
db.Tags.Add(new Tag
|
||||||
|
{
|
||||||
|
TagId = "TAG-2",
|
||||||
|
DriverInstanceId = "DRV-1",
|
||||||
|
EquipmentId = "EQ-1",
|
||||||
|
Name = "y",
|
||||||
|
DataType = "Float",
|
||||||
|
AccessLevel = TagAccessLevel.Read,
|
||||||
|
TagConfig = "{\"FullName\":\"DelmiaReceiver_001.Y\"}",
|
||||||
|
});
|
||||||
|
db.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await service.CreateVirtualTagAsync("EQ-1", Input());
|
||||||
|
|
||||||
|
result.Ok.ShouldBeFalse();
|
||||||
|
result.Error.ShouldNotBeNull();
|
||||||
|
result.Error.ShouldContain("EQ-1");
|
||||||
|
result.Error.ShouldContain("{{equip}}");
|
||||||
|
|
||||||
|
using var verifyDb = UnsTreeTestDb.CreateNamed(dbName);
|
||||||
|
verifyDb.VirtualTags.Any(v => v.VirtualTagId == "VTAG-1").ShouldBeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
// ----- Update -----
|
// ----- Update -----
|
||||||
|
|
||||||
/// <summary>{{equip}} script + a derivable base → update succeeds.</summary>
|
/// <summary>{{equip}} script + a derivable base → update succeeds.</summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user