using System.IO.Pipes;
using System.Text.Json;
using XFEEDToolBox.Core.Galaxy;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public sealed class NativeGalaxyCommodityCatalogTests
{
private static async Task Serve(int pid,object result,CancellationToken token,Action<JsonElement>? inspect=null)
{
await using var server=new NamedPipeServerStream($"XFEEDToolBox.Navigation.{pid}",PipeDirection.InOut,1,PipeTransmissionMode.Byte,PipeOptions.Asynchronous);
await server.WaitForConnectionAsync(token);var bytes=new byte[4096];var count=await server.ReadAsync(bytes,token);using(var json=JsonDocument.Parse(bytes.AsMemory(0,count)))inspect?.Invoke(json.RootElement);
await server.WriteAsync(JsonSerializer.SerializeToUtf8Bytes(new{ok=true,result}),token);await server.WriteAsync(new byte[]{10},token);if(OperatingSystem.IsWindows())server.WaitForPipeDrain();
}
private static object Row(uint uid,int kind=1)=>new{uid,name="原名称 \\\" "+uid,category="原类别",kind,publisherEligible=kind==1?(bool?)true:null};
[Test] public async Task OriginalNumericUidsPreserveZeroHighBitsAndUnknownInventoryAcrossStablePages()
{
var pid=Random.Shared.Next(180000000,190000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
var server=Task.Run(async()=>
{
await Serve(pid,new{available=true,generation=8,entityId="42",total=17,unresolvedCount=3,complete=false,nextOffset=(int?)16,items=Enumerable.Range(0,16).Select(i=>Row((uint)i))},stop.Token,r=>Check.Equal("galaxy.commodities",r.GetProperty("op").GetString()));
await Serve(pid,new{available=true,generation=8,entityId="42",total=17,unresolvedCount=3,complete=false,nextOffset=(int?)null,items=new[]{Row(0xFFFFFFFE,2)}},stop.Token,r=>{Check.Equal(16,r.GetProperty("offset").GetInt32());Check.Equal(8UL,r.GetProperty("generation").GetUInt64());});
});
var result=await new NativeGalaxyAccountCatalog(pid).ReadCommodityOptionsAsync(stop.Token);await server;
Check.That(result.Available&&!result.Complete&&result.UnresolvedCount==3);Check.Equal(0u,result.Options[0].Uid);Check.Equal(0xFFFFFFFEu,result.Options[16].Uid);Check.That(result.Options[16].PublisherEligible is null);Check.Equal("原类别",result.Options[0].Category);
}
[Test] public async Task ChangedDefinitionContextAndUnsupportedCompletenessCannotCreateAConfirmedSelection()
{
var pid=Random.Shared.Next(180000000,190000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
var server=Task.Run(async()=>
{
await Serve(pid,new{available=true,generation=8,entityId="42",total=17,unresolvedCount=0,complete=false,nextOffset=(int?)16,items=Enumerable.Range(0,16).Select(i=>Row((uint)i))},stop.Token);
await Serve(pid,new{available=true,generation=8,entityId="43",total=17,unresolvedCount=0,complete=false,nextOffset=(int?)null,items=new[]{Row(16)}},stop.Token);
});
var rejected=false;try{await new NativeGalaxyAccountCatalog(pid).ReadCommodityOptionsAsync(stop.Token);}catch(InvalidDataException){rejected=true;}await server;Check.That(rejected);
server=Task.Run(()=>Serve(pid,new{available=true,generation=9,entityId="42",total=0,unresolvedCount=0,complete=true,nextOffset=(int?)null,items=Array.Empty<object>()},stop.Token));
rejected=false;try{await new NativeGalaxyAccountCatalog(pid).ReadCommodityOptionsAsync(stop.Token);}catch(InvalidDataException){rejected=true;}await server;Check.That(rejected);
}
}
using System.IO.Pipes;
using System.Text.Json;
using XFEEDToolBox.Core.Galaxy;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public sealed class NativeGalaxyCommodityCatalogTests
{
private static async Task Serve(int pid,object result,CancellationToken token,Action<JsonElement>? inspect=null)
{
await using var server=new NamedPipeServerStream($"XFEEDToolBox.Navigation.{pid}",PipeDirection.InOut,1,PipeTransmissionMode.Byte,PipeOptions.Asynchronous);
await server.WaitForConnectionAsync(token);var bytes=new byte[4096];var count=await server.ReadAsync(bytes,token);using(var json=JsonDocument.Parse(bytes.AsMemory(0,count)))inspect?.Invoke(json.RootElement);
await server.WriteAsync(JsonSerializer.SerializeToUtf8Bytes(new{ok=true,result}),token);await server.WriteAsync(new byte[]{10},token);if(OperatingSystem.IsWindows())server.WaitForPipeDrain();
}
private static object Row(uint uid,int kind=1)=>new{uid,name="原名称 \\\" "+uid,category="原类别",kind,publisherEligible=kind==1?(bool?)true:null};
[Test] public async Task OriginalNumericUidsPreserveZeroHighBitsAndUnknownInventoryAcrossStablePages()
{
var pid=Random.Shared.Next(180000000,190000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
var server=Task.Run(async()=>
{
await Serve(pid,new{available=true,generation=8,entityId="42",total=17,unresolvedCount=3,complete=false,nextOffset=(int?)16,items=Enumerable.Range(0,16).Select(i=>Row((uint)i))},stop.Token,r=>Check.Equal("galaxy.commodities",r.GetProperty("op").GetString()));
await Serve(pid,new{available=true,generation=8,entityId="42",total=17,unresolvedCount=3,complete=false,nextOffset=(int?)null,items=new[]{Row(0xFFFFFFFE,2)}},stop.Token,r=>{Check.Equal(16,r.GetProperty("offset").GetInt32());Check.Equal(8UL,r.GetProperty("generation").GetUInt64());});
});
var result=await new NativeGalaxyAccountCatalog(pid).ReadCommodityOptionsAsync(stop.Token);await server;
Check.That(result.Available&&!result.Complete&&result.UnresolvedCount==3);Check.Equal(0u,result.Options[0].Uid);Check.Equal(0xFFFFFFFEu,result.Options[16].Uid);Check.That(result.Options[16].PublisherEligible is null);Check.Equal("原类别",result.Options[0].Category);
}
[Test] public async Task ChangedDefinitionContextAndUnsupportedCompletenessCannotCreateAConfirmedSelection()
{
var pid=Random.Shared.Next(180000000,190000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
var server=Task.Run(async()=>
{
await Serve(pid,new{available=true,generation=8,entityId="42",total=17,unresolvedCount=0,complete=false,nextOffset=(int?)16,items=Enumerable.Range(0,16).Select(i=>Row((uint)i))},stop.Token);
await Serve(pid,new{available=true,generation=8,entityId="43",total=17,unresolvedCount=0,complete=false,nextOffset=(int?)null,items=new[]{Row(16)}},stop.Token);
});
var rejected=false;try{await new NativeGalaxyAccountCatalog(pid).ReadCommodityOptionsAsync(stop.Token);}catch(InvalidDataException){rejected=true;}await server;Check.That(rejected);
server=Task.Run(()=>Serve(pid,new{available=true,generation=9,entityId="42",total=0,unresolvedCount=0,complete=true,nextOffset=(int?)null,items=Array.Empty<object>()},stop.Token));
rejected=false;try{await new NativeGalaxyAccountCatalog(pid).ReadCommodityOptionsAsync(stop.Token);}catch(InvalidDataException){rejected=true;}await server;Check.That(rejected);
}
}