namespace ZB.MOM.WW.MxGateway.Client.Tests;
public sealed class MxGatewayClientOptionsTests
{
///
/// The safe-unary budget covers every attempt's deadline plus the backoff between them, so a
/// first attempt that hits its deadline does not consume the retry's time (#197).
///
[Fact]
public void SafeUnaryBudget_CoversEveryAttemptAndBackoff()
{
var options = new MxGatewayClientOptions
{
Endpoint = new Uri("http://localhost:5000"),
ApiKey = "test-api-key",
DefaultCallTimeout = TimeSpan.FromSeconds(30),
Retry = new MxGatewayClientRetryOptions { MaxAttempts = 3, MaxDelay = TimeSpan.FromSeconds(2) },
};
Assert.Equal(TimeSpan.FromSeconds(94), MxGatewayClientRetryPolicy.SafeUnaryBudget(options));
}
/// A budget beyond what a cancellation timer accepts means no outer cap rather than a throw.
[Fact]
public void SafeUnaryBudget_WhenTooLargeForATimer_ReturnsNull()
{
var options = new MxGatewayClientOptions
{
Endpoint = new Uri("http://localhost:5000"),
ApiKey = "test-api-key",
DefaultCallTimeout = TimeSpan.FromDays(40),
Retry = new MxGatewayClientRetryOptions { MaxAttempts = 2 },
};
Assert.Null(MxGatewayClientRetryPolicy.SafeUnaryBudget(options));
}
/// Verifies that options with valid endpoint and API key pass validation.
[Fact]
public void Validate_WithAbsoluteEndpointAndApiKey_Succeeds()
{
var options = new MxGatewayClientOptions
{
Endpoint = new Uri("http://localhost:5000"),
ApiKey = "test-api-key",
};
options.Validate();
}
/// Verifies that empty API key causes validation to fail.
[Fact]
public void Validate_WithEmptyApiKey_Throws()
{
var options = new MxGatewayClientOptions
{
Endpoint = new Uri("http://localhost:5000"),
ApiKey = "",
};
Assert.Throws(options.Validate);
}
/// Verifies that invalid retry options cause validation to fail.
[Fact]
public void Validate_WithInvalidRetryOptions_Throws()
{
var options = new MxGatewayClientOptions
{
Endpoint = new Uri("http://localhost:5000"),
ApiKey = "test-api-key",
Retry = new MxGatewayClientRetryOptions { MaxAttempts = 0 },
};
Assert.Throws(options.Validate);
}
}