fix(multivalue): Wave-2 review fixes (MV-2/MV-4/MV-12)
- MV-2: guard unsupported element type before parse (no misleading re-wrap); add Float round-trip test - MV-4: carry ElementDataType through the two validation-flatten ResolvedAttribute sites (ManagementActor.HandleValidateTemplate, BundleImporter.BuildFlattenedConfigForValidation) so MV-5 validation sees element type via every entry point - MV-12: include ElementDataType in TemplateAttribute add/update audit payloads + fix stale docstring
This commit is contained in:
@@ -72,6 +72,8 @@ public static class AttributeValueCodec
|
|||||||
private static object? ParseScalar(string? s, DataType t)
|
private static object? ParseScalar(string? s, DataType t)
|
||||||
{
|
{
|
||||||
if (s is null) throw new FormatException("List elements may not be null.");
|
if (s is null) throw new FormatException("List elements may not be null.");
|
||||||
|
if (!IsValidElementType(t))
|
||||||
|
throw new FormatException($"Unsupported list element type '{t}'.");
|
||||||
var c = CultureInfo.InvariantCulture;
|
var c = CultureInfo.InvariantCulture;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -524,6 +524,7 @@ public class ManagementActor : ReceiveActor
|
|||||||
CanonicalName = a.Name,
|
CanonicalName = a.Name,
|
||||||
Value = a.Value,
|
Value = a.Value,
|
||||||
DataType = a.DataType.ToString(),
|
DataType = a.DataType.ToString(),
|
||||||
|
ElementDataType = a.ElementDataType?.ToString(),
|
||||||
IsLocked = a.IsLocked,
|
IsLocked = a.IsLocked,
|
||||||
DataSourceReference = a.DataSourceReference
|
DataSourceReference = a.DataSourceReference
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
|
|||||||
@@ -1083,8 +1083,8 @@ public sealed class BundleImporter : IBundleImporter
|
|||||||
/// enumerates for the "Template overwritten" action.
|
/// enumerates for the "Template overwritten" action.
|
||||||
/// <para>
|
/// <para>
|
||||||
/// Update detection compares every scalar field (Value, DataType,
|
/// Update detection compares every scalar field (Value, DataType,
|
||||||
/// IsLocked, Description, DataSourceReference) — no field change → no
|
/// ElementDataType, IsLocked, Description, DataSourceReference) — no field
|
||||||
/// audit row, so an idempotent overwrite produces no noise.
|
/// change → no audit row, so an idempotent overwrite produces no noise.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task SyncTemplateAttributesAsync(
|
private async Task SyncTemplateAttributesAsync(
|
||||||
@@ -1146,6 +1146,7 @@ public sealed class BundleImporter : IBundleImporter
|
|||||||
AttributeName = current.Name,
|
AttributeName = current.Name,
|
||||||
current.Value,
|
current.Value,
|
||||||
current.DataType,
|
current.DataType,
|
||||||
|
current.ElementDataType,
|
||||||
current.IsLocked,
|
current.IsLocked,
|
||||||
current.Description,
|
current.Description,
|
||||||
current.DataSourceReference,
|
current.DataSourceReference,
|
||||||
@@ -1176,6 +1177,7 @@ public sealed class BundleImporter : IBundleImporter
|
|||||||
AttributeName = newAttr.Name,
|
AttributeName = newAttr.Name,
|
||||||
newAttr.Value,
|
newAttr.Value,
|
||||||
newAttr.DataType,
|
newAttr.DataType,
|
||||||
|
newAttr.ElementDataType,
|
||||||
newAttr.IsLocked,
|
newAttr.IsLocked,
|
||||||
newAttr.Description,
|
newAttr.Description,
|
||||||
newAttr.DataSourceReference,
|
newAttr.DataSourceReference,
|
||||||
@@ -2304,6 +2306,7 @@ public sealed class BundleImporter : IBundleImporter
|
|||||||
CanonicalName = a.Name,
|
CanonicalName = a.Name,
|
||||||
Value = a.Value,
|
Value = a.Value,
|
||||||
DataType = a.DataType.ToString(),
|
DataType = a.DataType.ToString(),
|
||||||
|
ElementDataType = a.ElementDataType?.ToString(),
|
||||||
IsLocked = a.IsLocked,
|
IsLocked = a.IsLocked,
|
||||||
Description = a.Description,
|
Description = a.Description,
|
||||||
DataSourceReference = a.DataSourceReference,
|
DataSourceReference = a.DataSourceReference,
|
||||||
|
|||||||
@@ -49,6 +49,14 @@ public class AttributeValueCodecTests
|
|||||||
Assert.Equal("[\"ACME, Inc.\"]",
|
Assert.Equal("[\"ACME, Inc.\"]",
|
||||||
AttributeValueCodec.Encode(new List<string> { "ACME, Inc." }));
|
AttributeValueCodec.Encode(new List<string> { "ACME, Inc." }));
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RoundTrip_FloatList()
|
||||||
|
{
|
||||||
|
var json = AttributeValueCodec.Encode(new List<float> { 1.5f, 2.25f, -3.75f });
|
||||||
|
var back = (IList<float>)AttributeValueCodec.Decode(json, DataType.List, DataType.Float)!;
|
||||||
|
Assert.Equal(new[] { 1.5f, 2.25f, -3.75f }, back);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Encode_DoubleList_IsInvariant()
|
public void Encode_DoubleList_IsInvariant()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user