using System.Text.Json;
using XFEEDToolBox.Core.Execution;
using XFEEDToolBox.Core.Models;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public class ExternalTradeSettlementTests
{
private static PlayerState Player(int cargo=0)=>new(){InGame=true,CargoReliable=true,CargoCount=cargo,CommanderId="test",CurrentShipId=7};
private static async Task<string> Fixture(string directory,bool cargoProof=true,bool conflictingBuy=false)
{
var pending=Path.Combine(directory,"order.pending.json");
await File.WriteAllTextAsync(pending,JsonSerializer.Serialize(new{operationKey=Guid.NewGuid().ToString("N"),CommanderId="test",CurrentShipId=5,
created="2026-10-24T01:00:00Z",intent=new{Commodity="uranium",delta=192,unitPrice=7241,before=new{count=0}}}));
var lines=new List<object>{new{timestamp="2026-10-24T01:01:00Z",@event="LoadGame",FID="test",ShipID=5}};
if(cargoProof)lines.Add(new{timestamp="2026-10-24T01:02:00Z",@event="Cargo",Count=192,Inventory=new[]{new{Name="uranium",Count=192,Stolen=0}}});
if(conflictingBuy)lines.Add(new{timestamp="2026-10-24T01:02:30Z",@event="MarketBuy",Type="uranium",Count=192});
lines.Add(new{timestamp="2026-10-24T01:03:00Z",@event="MarketSell",Type="uranium",Count=192,AvgPricePaid=7241,SellPrice=57104,TotalSale=10963968,MarketID=99});
await File.WriteAllLinesAsync(Path.Combine(directory,"Journal.test.log"),lines.Select(row=>JsonSerializer.Serialize(row)));
return pending;
}
[Test]public async Task ActualManualSaleReconcilesWithoutRewritingTheFailedNativeOrder()
{
using var directory=new TemporaryDirectory();var pending=await Fixture(directory.Path);var before=await File.ReadAllTextAsync(pending);
await ExternalTradeSettlement.ReconcileAsync(directory.Path,directory.Path,Player(),JsonSerializer.SerializeToElement(new{verified=true,count=0,credits=10000}),default);
Check.That(ExternalTradeSettlement.IsSettled(pending,Player()));Check.Equal(before,await File.ReadAllTextAsync(pending));
Check.That(!File.Exists(pending.Replace(".pending.json",".confirmed.json")));
await File.AppendAllTextAsync(pending," ");Check.That(!ExternalTradeSettlement.IsSettled(pending,Player()));
}
[Test]public async Task MissingCargoOrASeparatePurchaseCannotResolveAnUnknownOrder()
{
foreach(var conflict in new[]{false,true})
{
using var directory=new TemporaryDirectory();var pending=await Fixture(directory.Path,conflict,conflict);
await ExternalTradeSettlement.ReconcileAsync(directory.Path,directory.Path,Player(),JsonSerializer.SerializeToElement(new{verified=true,count=0}),default);
Check.That(!ExternalTradeSettlement.IsSettled(pending,Player()));
}
}
[Test]public async Task CurrentCargoOrAnotherCommanderKeepsTheOrderUnresolved()
{
using var directory=new TemporaryDirectory();var pending=await Fixture(directory.Path);
await ExternalTradeSettlement.ReconcileAsync(directory.Path,directory.Path,Player(1),JsonSerializer.SerializeToElement(new{verified=true,count=1}),default);
Check.That(!ExternalTradeSettlement.IsSettled(pending,Player()));
await ExternalTradeSettlement.ReconcileAsync(directory.Path,directory.Path,Player() with{CommanderId="another"},JsonSerializer.SerializeToElement(new{verified=true,count=0}),default);
Check.That(!ExternalTradeSettlement.IsSettled(pending,Player()));
}
}
using System.Text.Json;
using XFEEDToolBox.Core.Execution;
using XFEEDToolBox.Core.Models;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public class ExternalTradeSettlementTests
{
private static PlayerState Player(int cargo=0)=>new(){InGame=true,CargoReliable=true,CargoCount=cargo,CommanderId="test",CurrentShipId=7};
private static async Task<string> Fixture(string directory,bool cargoProof=true,bool conflictingBuy=false)
{
var pending=Path.Combine(directory,"order.pending.json");
await File.WriteAllTextAsync(pending,JsonSerializer.Serialize(new{operationKey=Guid.NewGuid().ToString("N"),CommanderId="test",CurrentShipId=5,
created="2026-10-24T01:00:00Z",intent=new{Commodity="uranium",delta=192,unitPrice=7241,before=new{count=0}}}));
var lines=new List<object>{new{timestamp="2026-10-24T01:01:00Z",@event="LoadGame",FID="test",ShipID=5}};
if(cargoProof)lines.Add(new{timestamp="2026-10-24T01:02:00Z",@event="Cargo",Count=192,Inventory=new[]{new{Name="uranium",Count=192,Stolen=0}}});
if(conflictingBuy)lines.Add(new{timestamp="2026-10-24T01:02:30Z",@event="MarketBuy",Type="uranium",Count=192});
lines.Add(new{timestamp="2026-10-24T01:03:00Z",@event="MarketSell",Type="uranium",Count=192,AvgPricePaid=7241,SellPrice=57104,TotalSale=10963968,MarketID=99});
await File.WriteAllLinesAsync(Path.Combine(directory,"Journal.test.log"),lines.Select(row=>JsonSerializer.Serialize(row)));
return pending;
}
[Test]public async Task ActualManualSaleReconcilesWithoutRewritingTheFailedNativeOrder()
{
using var directory=new TemporaryDirectory();var pending=await Fixture(directory.Path);var before=await File.ReadAllTextAsync(pending);
await ExternalTradeSettlement.ReconcileAsync(directory.Path,directory.Path,Player(),JsonSerializer.SerializeToElement(new{verified=true,count=0,credits=10000}),default);
Check.That(ExternalTradeSettlement.IsSettled(pending,Player()));Check.Equal(before,await File.ReadAllTextAsync(pending));
Check.That(!File.Exists(pending.Replace(".pending.json",".confirmed.json")));
await File.AppendAllTextAsync(pending," ");Check.That(!ExternalTradeSettlement.IsSettled(pending,Player()));
}
[Test]public async Task MissingCargoOrASeparatePurchaseCannotResolveAnUnknownOrder()
{
foreach(var conflict in new[]{false,true})
{
using var directory=new TemporaryDirectory();var pending=await Fixture(directory.Path,conflict,conflict);
await ExternalTradeSettlement.ReconcileAsync(directory.Path,directory.Path,Player(),JsonSerializer.SerializeToElement(new{verified=true,count=0}),default);
Check.That(!ExternalTradeSettlement.IsSettled(pending,Player()));
}
}
[Test]public async Task CurrentCargoOrAnotherCommanderKeepsTheOrderUnresolved()
{
using var directory=new TemporaryDirectory();var pending=await Fixture(directory.Path);
await ExternalTradeSettlement.ReconcileAsync(directory.Path,directory.Path,Player(1),JsonSerializer.SerializeToElement(new{verified=true,count=1}),default);
Check.That(!ExternalTradeSettlement.IsSettled(pending,Player()));
await ExternalTradeSettlement.ReconcileAsync(directory.Path,directory.Path,Player() with{CommanderId="another"},JsonSerializer.SerializeToElement(new{verified=true,count=0}),default);
Check.That(!ExternalTradeSettlement.IsSettled(pending,Player()));
}
}