Issue #31: implement mxstatus proxy and hresult conversion
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using MxGateway.Contracts.Proto;
|
||||
using MxGateway.Worker.Conversion;
|
||||
|
||||
namespace MxGateway.Worker.Tests.Conversion;
|
||||
|
||||
public sealed class HResultConverterTests
|
||||
{
|
||||
private readonly HResultConverter _converter = new();
|
||||
|
||||
[Fact]
|
||||
public void Convert_WithComException_CapturesExceptionHResult()
|
||||
{
|
||||
COMException exception = new("Sensitive provider text should not be copied.", unchecked((int)0x80070057));
|
||||
|
||||
HResultConversion converted = _converter.Convert(exception);
|
||||
|
||||
Assert.Equal(unchecked((int)0x80070057), converted.HResult);
|
||||
Assert.Equal(ProtocolStatusCode.MxaccessFailure, converted.ProtocolStatus.Code);
|
||||
Assert.Contains("0x80070057", converted.ProtocolStatus.Message);
|
||||
Assert.Contains(typeof(COMException).FullName!, converted.DiagnosticMessage);
|
||||
Assert.DoesNotContain("Sensitive provider text", converted.DiagnosticMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateProtocolStatus_WithSuccessHResult_ReturnsOk()
|
||||
{
|
||||
ProtocolStatus status = _converter.CreateProtocolStatus(0);
|
||||
|
||||
Assert.Equal(ProtocolStatusCode.Ok, status.Code);
|
||||
Assert.Equal("HRESULT 0x00000000", status.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Convert_WithNonComException_CapturesExceptionHResult()
|
||||
{
|
||||
InvalidOperationException exception = new("do not include this");
|
||||
|
||||
HResultConversion converted = _converter.Convert(exception);
|
||||
|
||||
Assert.Equal(exception.HResult, converted.HResult);
|
||||
Assert.Equal(ProtocolStatusCode.MxaccessFailure, converted.ProtocolStatus.Code);
|
||||
Assert.Contains("0x", converted.DiagnosticMessage);
|
||||
Assert.DoesNotContain("do not include this", converted.DiagnosticMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MxGateway.Contracts.Proto;
|
||||
using MxGateway.Worker.Conversion;
|
||||
|
||||
namespace MxGateway.Worker.Tests.Conversion;
|
||||
|
||||
public sealed class MxStatusProxyConverterTests
|
||||
{
|
||||
private readonly MxStatusProxyConverter _converter = new();
|
||||
|
||||
[Fact]
|
||||
public void Convert_WithStatusStruct_PreservesStatusFields()
|
||||
{
|
||||
FakeMxStatusProxy status = new()
|
||||
{
|
||||
success = 1,
|
||||
category = 5,
|
||||
detectedBy = 3,
|
||||
detail = 21,
|
||||
};
|
||||
|
||||
MxStatusProxy converted = _converter.Convert(status);
|
||||
|
||||
Assert.Equal(1, converted.Success);
|
||||
Assert.Equal(MxStatusCategory.OperationalError, converted.Category);
|
||||
Assert.Equal(MxStatusSource.RespondingNmx, converted.DetectedBy);
|
||||
Assert.Equal(21, converted.Detail);
|
||||
Assert.Equal(5, converted.RawCategory);
|
||||
Assert.Equal(3, converted.RawDetectedBy);
|
||||
Assert.Equal("Invalid reference", converted.DiagnosticText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConvertMany_WithStatusArray_DoesNotCollapseEntries()
|
||||
{
|
||||
FakeMxStatusProxy[] statuses =
|
||||
[
|
||||
new()
|
||||
{
|
||||
success = 1,
|
||||
category = 0,
|
||||
detectedBy = 0,
|
||||
detail = 0,
|
||||
},
|
||||
new()
|
||||
{
|
||||
success = 0,
|
||||
category = 6,
|
||||
detectedBy = 5,
|
||||
detail = 33,
|
||||
},
|
||||
];
|
||||
|
||||
IReadOnlyList<MxStatusProxy> converted = _converter.ConvertMany(statuses);
|
||||
|
||||
Assert.Equal(2, converted.Count);
|
||||
Assert.Equal(MxStatusCategory.Ok, converted[0].Category);
|
||||
Assert.Equal(MxStatusCategory.SecurityError, converted[1].Category);
|
||||
Assert.Equal(MxStatusSource.RespondingAutomationObject, converted[1].DetectedBy);
|
||||
Assert.Equal("Write access denied", converted[1].DiagnosticText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Convert_WithUnknownCategoryAndSource_PreservesRawFields()
|
||||
{
|
||||
FakeMxStatusProxy status = new()
|
||||
{
|
||||
success = -1,
|
||||
category = 99,
|
||||
detectedBy = 42,
|
||||
detail = 1234,
|
||||
};
|
||||
|
||||
MxStatusProxy converted = _converter.Convert(status);
|
||||
|
||||
Assert.Equal(-1, converted.Success);
|
||||
Assert.Equal(MxStatusCategory.Unknown, converted.Category);
|
||||
Assert.Equal(MxStatusSource.Unknown, converted.DetectedBy);
|
||||
Assert.Equal(99, converted.RawCategory);
|
||||
Assert.Equal(42, converted.RawDetectedBy);
|
||||
Assert.Equal(1234, converted.Detail);
|
||||
Assert.Equal(string.Empty, converted.DiagnosticText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PreserveCompletionOnlyStatusBytes_ReturnsRawHexMetadata()
|
||||
{
|
||||
string rawStatus = _converter.PreserveCompletionOnlyStatusBytes(
|
||||
[0x00, 0x00, 0x50, 0x80, 0x00]);
|
||||
|
||||
Assert.Equal("completion_only_status_hex=0000508000", rawStatus);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Convert_WithMissingStatusField_ThrowsConversionException()
|
||||
{
|
||||
MxStatusConversionException exception =
|
||||
Assert.Throws<MxStatusConversionException>(() => _converter.Convert(new MissingFields()));
|
||||
|
||||
Assert.Contains("success", exception.Message);
|
||||
}
|
||||
|
||||
public struct FakeMxStatusProxy
|
||||
{
|
||||
public short success;
|
||||
|
||||
public int category;
|
||||
|
||||
public int detectedBy;
|
||||
|
||||
public short detail;
|
||||
}
|
||||
|
||||
private sealed class MissingFields
|
||||
{
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user