using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Commons.Protos;
using ZB.MOM.WW.OtOpcUa.Commons.Protos.MeshTransport.V1;
namespace ZB.MOM.WW.OtOpcUa.Commons.Tests;
///
/// Contract-lock for the mesh command envelope's oneof. If a fifth command is added
/// to mesh_transport.proto without adding a matching entry to
/// , this test goes red — the single guard
/// that keeps the wire contract and the handled-case set from silently drifting apart. A drift
/// here is exactly the failure the whole transport exists to avoid: a command that crosses the
/// mesh boundary, decodes to a case nobody handles, and is dropped without a trace.
///
public class MeshTransportProtoContractTests
{
[Fact]
public void EveryOneofVariant_IsAccountedFor()
{
var variants = System.Enum.GetValues()
.Where(c => c != CommandEnvelope.CommandOneofCase.None).ToArray();
variants.ShouldBe(MeshTransportProtoContract.HandledCases, ignoreOrder: true);
}
[Fact]
public void The_service_base_and_client_types_generate()
{
// Referencing these types is the whole assertion — GrpcServices="Both" must emit both halves
// of both services: central hosts CentralCommandService and dials NodeCommandService, and a
// driver node does the mirror image, so neither service can ship client-only or server-only.
typeof(NodeCommandService.NodeCommandServiceBase).ShouldNotBeNull();
typeof(NodeCommandService.NodeCommandServiceClient).ShouldNotBeNull();
typeof(CentralCommandService.CentralCommandServiceBase).ShouldNotBeNull();
typeof(CentralCommandService.CentralCommandServiceClient).ShouldNotBeNull();
}
[Fact]
public void The_apply_outcome_enum_reserves_zero_as_unspecified()
{
// proto3 decodes an absent enum field as 0. If 0 meant "Applied", a message that lost the
// field in transit — or was written by a peer that predates it — would report a deployment
// as successfully applied when nothing was said at all. 0 must stay meaningless.
((int)ApplyOutcome.Unspecified).ShouldBe(0);
((int)ApplyOutcome.Applied).ShouldNotBe(0);
((int)ApplyOutcome.Failed).ShouldNotBe(0);
}
}