using System.Text.Json;
using System.Text.Json.Nodes;
using XFEEDToolBox.Core.Navigation;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public class ScoStartRefusalTests
{
private static readonly DateTimeOffset Now=DateTimeOffset.FromUnixTimeMilliseconds(1700000000000);
private static readonly SystemFlightFrame Frame=new(){InGame=true,GeometryVerified=true,Mode=LocalFlightMode.Supercruise,ShipEntity=12,ReferenceWorld=24,ObservedAt=Now};
private static JsonObject Status()=>JsonSerializer.SerializeToNode(new{owned=false,sample=new{verified=true,entityId="12",referenceWorldAddress="24",inSupercruise=true,
stableFsd=true,rawFsdState=2,playerOverride=false,state=0,observedAtUnixMilliseconds=Now.ToUnixTimeMilliseconds()},receipt=new{owner="owner",requestId="request",generation=7,
selectionGeneration=8,failed=true,applied=false,nativeMethodCalled=false,reason="geometry-or-assist",gate=new{identityVerified=true,targetVerified=true,emergency=false,damageSeen=false,
assistEnabled=false,hullFraction=1.0}}})!.AsObject();
private static bool Allowed(JsonObject status,SystemFlightFrame? frame=null)
{var value=JsonSerializer.SerializeToElement(status);return ScoStartRefusal.CanContinueOrdinaryFlight(value,value.GetProperty("receipt"),"owner","request",7,8,frame??Frame,Now);}
[Test]public void MatchingNeverStartedCollisionRefusalPreservesOrdinaryFlight()
{
Check.That(Allowed(Status()));
foreach(var reason in new[]{"approach-or-alignment","native-refusal","fuel","heat","thermal-model"})
{var status=Status();status["receipt"]!["reason"]=reason;Check.That(Allowed(status));}
}
[Test]public void OwnedActiveForeignOrUnacknowledgedScoCannotBeTreatedAsAnOptionalRefusal()
{
foreach(var alter in new Action<JsonObject>[]
{s=>s["owned"]=true,s=>s["sample"]!["state"]=2,s=>s["sample"]!["entityId"]="99",s=>s["sample"]!["referenceWorldAddress"]="99",
s=>s["receipt"]!["owner"]="foreign",s=>s["receipt"]!["requestId"]="foreign",s=>s["receipt"]!["generation"]=6,s=>s["receipt"]!["selectionGeneration"]=6,
s=>s["receipt"]!["nativeMethodCalled"]=true,s=>s["receipt"]!["applied"]=true,s=>s["receipt"]!["failed"]=false,s=>s["receipt"]!.AsObject().Remove("nativeMethodCalled")})
{var status=Status();alter(status);Check.That(!Allowed(status));}
}
[Test]public void ActualSafetyIdentityTelemetryAndAssistFailuresStillInterruptControl()
{
foreach(var alter in new Action<JsonObject>[]
{s=>s["receipt"]!["reason"]="health",s=>s["receipt"]!["reason"]="identity-or-target",s=>s["receipt"]!["gate"]!["emergency"]=true,s=>s["receipt"]!["gate"]!["damageSeen"]=true,
s=>s["receipt"]!["gate"]!["hullFraction"]=0,s=>s["receipt"]!["gate"]!["assistEnabled"]=true,s=>s["sample"]!["playerOverride"]=true,
s=>s["sample"]!["observedAtUnixMilliseconds"]=Now.AddSeconds(-1).ToUnixTimeMilliseconds(),s=>s["sample"]!["observedAtUnixMilliseconds"]=long.MinValue,s=>s["sample"]!["state"]="bad",
s=>s["receipt"]!["gate"]!["hullFraction"]="bad"})
{var status=Status();alter(status);Check.That(!Allowed(status));}
Check.That(!Allowed(Status(),Frame with{PlayerOverride=true}));Check.That(!Allowed(Status(),Frame with{ExternalThreat=true}));
Check.That(!Allowed(Status(),Frame with{ObservedAt=Now.AddSeconds(-1)}));
}
}
using System.Text.Json;
using System.Text.Json.Nodes;
using XFEEDToolBox.Core.Navigation;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public class ScoStartRefusalTests
{
private static readonly DateTimeOffset Now=DateTimeOffset.FromUnixTimeMilliseconds(1700000000000);
private static readonly SystemFlightFrame Frame=new(){InGame=true,GeometryVerified=true,Mode=LocalFlightMode.Supercruise,ShipEntity=12,ReferenceWorld=24,ObservedAt=Now};
private static JsonObject Status()=>JsonSerializer.SerializeToNode(new{owned=false,sample=new{verified=true,entityId="12",referenceWorldAddress="24",inSupercruise=true,
stableFsd=true,rawFsdState=2,playerOverride=false,state=0,observedAtUnixMilliseconds=Now.ToUnixTimeMilliseconds()},receipt=new{owner="owner",requestId="request",generation=7,
selectionGeneration=8,failed=true,applied=false,nativeMethodCalled=false,reason="geometry-or-assist",gate=new{identityVerified=true,targetVerified=true,emergency=false,damageSeen=false,
assistEnabled=false,hullFraction=1.0}}})!.AsObject();
private static bool Allowed(JsonObject status,SystemFlightFrame? frame=null)
{var value=JsonSerializer.SerializeToElement(status);return ScoStartRefusal.CanContinueOrdinaryFlight(value,value.GetProperty("receipt"),"owner","request",7,8,frame??Frame,Now);}
[Test]public void MatchingNeverStartedCollisionRefusalPreservesOrdinaryFlight()
{
Check.That(Allowed(Status()));
foreach(var reason in new[]{"approach-or-alignment","native-refusal","fuel","heat","thermal-model"})
{var status=Status();status["receipt"]!["reason"]=reason;Check.That(Allowed(status));}
}
[Test]public void OwnedActiveForeignOrUnacknowledgedScoCannotBeTreatedAsAnOptionalRefusal()
{
foreach(var alter in new Action<JsonObject>[]
{s=>s["owned"]=true,s=>s["sample"]!["state"]=2,s=>s["sample"]!["entityId"]="99",s=>s["sample"]!["referenceWorldAddress"]="99",
s=>s["receipt"]!["owner"]="foreign",s=>s["receipt"]!["requestId"]="foreign",s=>s["receipt"]!["generation"]=6,s=>s["receipt"]!["selectionGeneration"]=6,
s=>s["receipt"]!["nativeMethodCalled"]=true,s=>s["receipt"]!["applied"]=true,s=>s["receipt"]!["failed"]=false,s=>s["receipt"]!.AsObject().Remove("nativeMethodCalled")})
{var status=Status();alter(status);Check.That(!Allowed(status));}
}
[Test]public void ActualSafetyIdentityTelemetryAndAssistFailuresStillInterruptControl()
{
foreach(var alter in new Action<JsonObject>[]
{s=>s["receipt"]!["reason"]="health",s=>s["receipt"]!["reason"]="identity-or-target",s=>s["receipt"]!["gate"]!["emergency"]=true,s=>s["receipt"]!["gate"]!["damageSeen"]=true,
s=>s["receipt"]!["gate"]!["hullFraction"]=0,s=>s["receipt"]!["gate"]!["assistEnabled"]=true,s=>s["sample"]!["playerOverride"]=true,
s=>s["sample"]!["observedAtUnixMilliseconds"]=Now.AddSeconds(-1).ToUnixTimeMilliseconds(),s=>s["sample"]!["observedAtUnixMilliseconds"]=long.MinValue,s=>s["sample"]!["state"]="bad",
s=>s["receipt"]!["gate"]!["hullFraction"]="bad"})
{var status=Status();alter(status);Check.That(!Allowed(status));}
Check.That(!Allowed(Status(),Frame with{PlayerOverride=true}));Check.That(!Allowed(Status(),Frame with{ExternalThreat=true}));
Check.That(!Allowed(Status(),Frame with{ObservedAt=Now.AddSeconds(-1)}));
}
}