using System; using System.IO; using System.Linq; using Junction.Domain.Models; using Junction.Protocols.MTConnect.Parsing; using Xunit; namespace Junction.Tests.Unit { public sealed class MtconnectParserTests { private static readonly Guid MachineId = Guid.Parse("11111111-2222-3333-4444-555555555555"); private static string LoadFixture(string name) { var path = Path.Combine(AppContext.BaseDirectory, "Fixtures", "mtconnect", name); return File.ReadAllText(path); } // ---- PROBE ---- [Fact] public void Probe_ParsesDataItemDescriptors() { var result = MtconnectProbeParser.Parse(LoadFixture("probe.xml")); Assert.True(result.IsSuccess); var items = result.Value; Assert.True(items.Count > 0); // Spot-check a known DataItem from the fixture. var pos = items.SingleOrDefault(d => d.Id == "x1_pos"); Assert.NotNull(pos); Assert.Equal("POSITION", pos!.Type); Assert.Equal("SAMPLE", pos.Category); Assert.Equal("ACTUAL", pos.SubType); Assert.Equal("MILLIMETER", pos.Units); Assert.Equal("dev1", pos.DeviceId); Assert.Equal("junction-vmc-01", pos.DeviceUuid); // Availability descriptor present. Assert.Contains(items, d => d.Id == "dev1_avail" && d.Type == "AVAILABILITY"); } [Fact] public void Probe_MalformedRoot_Fails() { var result = MtconnectProbeParser.Parse(""); Assert.False(result.IsSuccess); Assert.False(result.WasCancelled); Assert.NotEmpty(result.Errors); } // ---- CURRENT ---- [Fact] public void Current_ParsesSnapshot_WithKnownObservations() { var result = MtconnectCurrentParser.Parse(LoadFixture("current.xml"), MachineId); Assert.True(result.IsSuccess); var snapshot = result.Value; Assert.Equal(MachineId, snapshot.MachineId); Assert.False(snapshot.IsEmpty); // Known position value. var xPos = snapshot.TryGetItem("x1_pos"); Assert.NotNull(xPos); Assert.Equal("125.4300", xPos!.Value); Assert.Equal("Position", xPos.Name); Assert.Equal("Samples", xPos.Category); // EXECUTION = ACTIVE. var exec = snapshot.TryGetItem("path1_exec"); Assert.NotNull(exec); Assert.Equal("ACTIVE", exec!.Value); // Condition state carried as value. var tempCond = snapshot.TryGetItem("c1_temp_cond"); Assert.NotNull(tempCond); Assert.Equal("Condition", tempCond!.Category); Assert.Equal("Normal", tempCond.Value); // AVAILABILITY -> Connected. Assert.Equal(ConnectionState.Connected, snapshot.ConnectionState); // CapturedAt = latest observed timestamp (10240 seq @ .240Z). Assert.Equal( DateTimeOffset.Parse("2026-07-21T09:15:30.240Z"), snapshot.CapturedAt); } [Fact] public void Current_Unavailable_YieldsDisconnected() { var result = MtconnectCurrentParser.Parse(LoadFixture("current_unavailable.xml"), MachineId); Assert.True(result.IsSuccess); Assert.Equal(ConnectionState.Disconnected, result.Value.ConnectionState); } [Fact] public void Current_Malformed_FailsWithoutThrowing() { // current_malformed.xml is truncated (unclosed elements) -> XmlException internally. var result = MtconnectCurrentParser.Parse(LoadFixture("current_malformed.xml"), MachineId); Assert.False(result.IsSuccess); Assert.False(result.WasCancelled); Assert.NotEmpty(result.Errors); } // ---- VERSION-AGNOSTIC PROOF ---- [Fact] public void Current_IsNamespaceVersionAgnostic() { var v17 = LoadFixture("current.xml"); var v20 = v17.Replace(":1.7", ":2.0"); Assert.Contains(":2.0", v20); Assert.DoesNotContain(":1.7", v20); var r17 = MtconnectCurrentParser.Parse(v17, MachineId); var r20 = MtconnectCurrentParser.Parse(v20, MachineId); Assert.True(r17.IsSuccess); Assert.True(r20.IsSuccess); var s17 = r17.Value; var s20 = r20.Value; Assert.Equal(s17.Items.Count, s20.Items.Count); Assert.Equal(s17.ConnectionState, s20.ConnectionState); Assert.Equal(s17.CapturedAt, s20.CapturedAt); // Item-by-item identical (id, value, category, timestamp). foreach (var a in s17.Items) { var b = s20.TryGetItem(a.Id); Assert.NotNull(b); Assert.Equal(a.Value, b!.Value); Assert.Equal(a.Category, b.Category); Assert.Equal(a.Name, b.Name); Assert.Equal(a.Timestamp, b.Timestamp); } } [Fact] public void Probe_IsNamespaceVersionAgnostic() { var v17 = LoadFixture("probe.xml"); var v20 = v17.Replace(":1.7", ":2.0"); var r17 = MtconnectProbeParser.Parse(v17); var r20 = MtconnectProbeParser.Parse(v20); Assert.True(r17.IsSuccess); Assert.True(r20.IsSuccess); Assert.Equal(r17.Value.Count, r20.Value.Count); } } }