fix(management-service): resolve ManagementService-004,006,007,013 — PipeTo dispatch, JsonDocument disposal, unified serialization, endpoint tests; re-triage MS-009
This commit is contained in:
@@ -668,4 +668,66 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Equal(envelope.CorrelationId, response.CorrelationId);
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Serialization (finding ManagementService-007)
|
||||
//
|
||||
// Command results are serialized with System.Text.Json configured with
|
||||
// ReferenceHandler.IgnoreCycles, so an entity graph with a bidirectional
|
||||
// navigation property does not throw. Property names are camelCase, which
|
||||
// the CLI's case-insensitive deserializer accepts.
|
||||
// ========================================================================
|
||||
|
||||
private sealed class CyclicNode
|
||||
{
|
||||
public string Name { get; set; } = "";
|
||||
public CyclicNode? Parent { get; set; }
|
||||
public List<CyclicNode> Children { get; set; } = new();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SerializeResult_WithCyclicGraph_DoesNotThrow()
|
||||
{
|
||||
var parent = new CyclicNode { Name = "Parent" };
|
||||
var child = new CyclicNode { Name = "Child", Parent = parent };
|
||||
parent.Children.Add(child); // parent <-> child cycle
|
||||
|
||||
var json = ManagementActor.SerializeResult(parent);
|
||||
|
||||
Assert.Contains("Parent", json);
|
||||
Assert.Contains("Child", json);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SerializeResult_UsesCamelCasePropertyNames()
|
||||
{
|
||||
var json = ManagementActor.SerializeResult(new CyclicNode { Name = "X" });
|
||||
|
||||
Assert.Contains("\"name\"", json);
|
||||
Assert.DoesNotContain("\"Name\"", json);
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// PipeTo fault mapping (finding ManagementService-004)
|
||||
//
|
||||
// Command processing is piped back via PipeTo; a fault raised inside
|
||||
// DispatchCommand must be mapped to ManagementError by the failure
|
||||
// continuation rather than escaping or being silently dropped.
|
||||
// ========================================================================
|
||||
|
||||
[Fact]
|
||||
public void UnknownCommandType_FaultMappedToManagementError()
|
||||
{
|
||||
// ManagementEnvelope.Command is typed object; an unrecognised payload
|
||||
// makes DispatchCommand throw NotSupportedException. The PipeTo failure
|
||||
// continuation must map it to ManagementError.
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope("not-a-command");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
||||
Assert.Equal(envelope.CorrelationId, response.CorrelationId);
|
||||
Assert.Equal("COMMAND_FAILED", response.ErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user