fix(inbound-api): resolve InboundAPI-014..017 — return-value validation, reflection-gateway hardening, deadline-bound routed calls, RouteHelper test coverage
This commit is contained in:
118
tests/ScadaLink.InboundAPI.Tests/ReturnValueValidatorTests.cs
Normal file
118
tests/ScadaLink.InboundAPI.Tests/ReturnValueValidatorTests.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
namespace ScadaLink.InboundAPI.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// InboundAPI-014: tests for return-value validation against a method's
|
||||
/// <c>ReturnDefinition</c>. Previously the script's return value was serialized
|
||||
/// verbatim with no checking against the declared return structure.
|
||||
/// </summary>
|
||||
public class ReturnValueValidatorTests
|
||||
{
|
||||
// --- No definition → no validation (backward compatible) ---
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData(" ")]
|
||||
public void NoReturnDefinition_AnythingIsValid(string? returnDefinition)
|
||||
{
|
||||
var result = ReturnValueValidator.Validate("{\"anything\":1}", returnDefinition);
|
||||
Assert.True(result.IsValid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NoReturnDefinition_NullResult_IsValid()
|
||||
{
|
||||
var result = ReturnValueValidator.Validate(null, null);
|
||||
Assert.True(result.IsValid);
|
||||
}
|
||||
|
||||
// --- Happy path: result matches the declared field shape ---
|
||||
|
||||
[Fact]
|
||||
public void ResultMatchingDefinition_IsValid()
|
||||
{
|
||||
const string def = """[{"name":"siteName","type":"String"},{"name":"totalUnits","type":"Integer"}]""";
|
||||
const string json = """{"siteName":"Site Alpha","totalUnits":14250}""";
|
||||
|
||||
var result = ReturnValueValidator.Validate(json, def);
|
||||
|
||||
Assert.True(result.IsValid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResultWithListField_ShapeChecked_IsValid()
|
||||
{
|
||||
const string def = """[{"name":"lines","type":"List"}]""";
|
||||
const string json = """{"lines":[{"lineName":"Line-1","units":8200}]}""";
|
||||
|
||||
var result = ReturnValueValidator.Validate(json, def);
|
||||
|
||||
Assert.True(result.IsValid);
|
||||
}
|
||||
|
||||
// --- Mismatches must be reported ---
|
||||
|
||||
[Fact]
|
||||
public void ResultMissingDeclaredField_IsInvalid()
|
||||
{
|
||||
const string def = """[{"name":"siteName","type":"String"},{"name":"totalUnits","type":"Integer"}]""";
|
||||
const string json = """{"siteName":"Site Alpha"}""";
|
||||
|
||||
var result = ReturnValueValidator.Validate(json, def);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Contains("totalUnits", result.ErrorMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResultFieldWrongType_IsInvalid()
|
||||
{
|
||||
const string def = """[{"name":"totalUnits","type":"Integer"}]""";
|
||||
const string json = """{"totalUnits":"not-a-number"}""";
|
||||
|
||||
var result = ReturnValueValidator.Validate(json, def);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Contains("totalUnits", result.ErrorMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullResultWhenStructureRequired_IsInvalid()
|
||||
{
|
||||
const string def = """[{"name":"siteName","type":"String"}]""";
|
||||
|
||||
var result = ReturnValueValidator.Validate(null, def);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NonObjectResultWhenStructureRequired_IsInvalid()
|
||||
{
|
||||
const string def = """[{"name":"siteName","type":"String"}]""";
|
||||
|
||||
var result = ReturnValueValidator.Validate("42", def);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ListFieldGivenNonArray_IsInvalid()
|
||||
{
|
||||
const string def = """[{"name":"lines","type":"List"}]""";
|
||||
const string json = """{"lines":"not-a-list"}""";
|
||||
|
||||
var result = ReturnValueValidator.Validate(json, def);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Contains("lines", result.ErrorMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MalformedReturnDefinition_IsInvalid()
|
||||
{
|
||||
var result = ReturnValueValidator.Validate("{\"x\":1}", "%%% not json %%%");
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user