using QVPN.Core; internal static class SubscriptionRefreshPolicyTests { public static async Task RunAsync(Func test) { var now = DateTimeOffset.Parse("2026-10-06T21:00:00Z"); await test("Service startup refreshes stale or undated subscription before health succeeds", () => { var policy = new SubscriptionRefreshPolicy(); Check(policy.ShouldRefreshOnConnect(now.AddHours(-2), now)); Check(policy.ShouldRefreshOnConnect(null, now)); Check(policy.ShouldRefreshOnConnect(now.AddMinutes(-15), now)); Check(!policy.ShouldRefreshOnConnect(now.AddMinutes(-14), now)); }); await test("A new explicit connect checks current endpoint even with recently cached subscription", () => { var policy = new SubscriptionRefreshPolicy(); Check(policy.ShouldRefreshOnConnect(now, now, explicitConnect: true)); policy.Attempted(now); Check(!policy.ShouldRefreshOnConnect(now, now.AddSeconds(59), explicitConnect: true)); Check(policy.ShouldRefreshOnConnect(now, now.AddSeconds(60), explicitConnect: true)); }); await test("Endpoint outage refresh is allowed without a connected engine and limited to once per minute", () => { var policy = new SubscriptionRefreshPolicy(); Check(policy.ShouldRefreshAfterEndpointFailure(now)); policy.Attempted(now); for (int seconds = 0; seconds < 60; seconds++) Check(!policy.ShouldRefreshAfterEndpointFailure(now.AddSeconds(seconds))); Check(policy.ShouldRefreshAfterEndpointFailure(now.AddSeconds(60))); }); await test("Manual or routine subscription attempts also suppress immediate outage refresh loops", () => { var policy = new SubscriptionRefreshPolicy(); policy.Attempted(now); Check(!policy.ShouldRefreshAfterEndpointFailure(now.AddSeconds(1))); Check(!policy.ShouldRefreshOnConnect(now.AddHours(-2), now.AddSeconds(1))); policy.Attempted(now.AddSeconds(60)); Check(!policy.ShouldRefreshAfterEndpointFailure(now.AddSeconds(61))); }); await test("A fresh successful subscription prevents automatic startup refresh after the retry cooldown", () => { var policy = new SubscriptionRefreshPolicy(); policy.Attempted(now); Check(!policy.ShouldRefreshOnConnect(now, now.AddMinutes(2))); Check(policy.ShouldRefreshOnConnect(now, now.AddMinutes(15))); }); await test("Clock rollback does not cause repeated automatic subscription refresh", () => { var policy = new SubscriptionRefreshPolicy(); policy.Attempted(now); Check(!policy.ShouldRefreshAfterEndpointFailure(now.AddMinutes(-5))); Check(!policy.ShouldRefreshOnConnect(now.AddHours(-2), now.AddMinutes(-5), explicitConnect: true)); }); } private static void Check(bool condition) { if (!condition) throw new InvalidOperationException("Subscription refresh policy regression."); } }