XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.IO.Pipes;
using System.Text.Json;
using XFEEDToolBox.Core.Galaxy;
using XFEExtension.NetCore.XUnit.Attributes;

namespace XFEEDToolBox.Test;

[TestFixture]
public sealed class NativeGalaxyAccountCatalogTests
{
    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 request=new byte[4096];var count=await server.ReadAsync(request,token);
        using(var json=JsonDocument.Parse(request.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(int i)=>new{uid=(9007199254740993UL+(ulong)i).ToString(),systemAddress=(9007199254740993L+i).ToString(),systemName="Actual recorded name "+i,name="Private label "+i,sourceKind=i%2+1,favourite=i%2==0};
    [Test] public async Task ThargoidCacheKeepsActualAddressesRecommendationOrderAndUnknownReadiness()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var server=Task.Run(()=>Serve(pid,new{available=true,generation=9,total=3,entityId="42",metadataObserved=false,responseObserved=true,
            states=Enumerable.Range(33,6).Select(s=>new{state=s,count=(uint?)null}),items=new object[]{
                new{kind="signal",id=0,systemAddress="9007199254740993",stronghold=false,affectedSystemsCount=(int?)null},
                new{kind="recommended",id=33<<8,state=33,rank=0,systemAddress="9007199254740994",progress=.8f},
                new{kind="recommended",id=33<<8|1,state=33,rank=1,systemAddress="9007199254740995",progress=.3f}}},stop.Token,
                r=>Check.Equal("galaxy.thargoid",r.GetProperty("op").GetString())));
        var result=await new NativeGalaxyAccountCatalog(pid).ReadThargoidAsync(stop.Token);await server;
        Check.That(result.Available&&!result.Ready&&!result.Complete);Check.That(result.States.All(s=>s.Count is null));
        Check.Equal(9007199254740993L,result.Signals[0].SystemAddress);Check.That(!result.Signals[0].Stronghold);
        Check.Equal(2,result.Recommended.Count);Check.Equal(.8f,result.Recommended[0].Progress);Check.Equal(1,result.Recommended[1].Rank);
    }
    [Test] public async Task ThargoidUnreadyCountCannotBeReportedAsZeroAndUiIdsCannotBecomeAddresses()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var server=Task.Run(()=>Serve(pid,new{available=true,generation=9,total=0,entityId="42",metadataObserved=false,responseObserved=true,
            states=Enumerable.Range(33,6).Select(s=>new{state=s,count=(uint?)0}),items=Array.Empty<object>()},stop.Token));
        var rejected=false;try{await new NativeGalaxyAccountCatalog(pid).ReadThargoidAsync(stop.Token);}catch(InvalidDataException){rejected=true;}
        await server;Check.That(rejected);
        server=Task.Run(()=>Serve(pid,new{available=true,generation=9,total=1,entityId="42",metadataObserved=true,responseObserved=true,
            states=Enumerable.Range(33,6).Select(s=>new{state=s,count=(uint?)0}),items=new[]{new{kind="recommended",id=0,state=33,rank=0,systemAddress="9007199254740993",progress=.5f}}},stop.Token));
        rejected=false;try{await new NativeGalaxyAccountCatalog(pid).ReadThargoidAsync(stop.Token);}catch(InvalidDataException){rejected=true;}
        await server;Check.That(rejected);
    }
    [Test] public async Task PowerDefinitionsKeepInternalAndUiIdsSeparateAndRetainHdrValues()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var server=Task.Run(()=>Serve(pid,new{available=true,optionsComplete=true,generation=9,total=2,entityId="42",items=new[]{
            new{index=0,uiPowerId=1,internalPowerId=17,name="First recorded definition",rawRed=12f,rawGreen=.25f,rawBlue=0f},
            new{index=1,uiPowerId=2,internalPowerId=4,name="Second recorded definition",rawRed=0f,rawGreen=1f,rawBlue=0f}}},stop.Token,r=>Check.Equal("galaxy.powers",r.GetProperty("op").GetString())));
        var result=await new NativeGalaxyAccountCatalog(pid).ReadPowerOptionsAsync(stop.Token);await server;
        Check.That(result.Available&&result.OptionsComplete);Check.Equal(1,result.Options[0].UiPowerId);Check.Equal(17,result.Options[0].InternalPowerId);Check.Equal(12f,result.Options[0].RawRed);
        Check.Equal(4,result.Options[1].InternalPowerId);
    }
    [Test] public async Task CommunityGoalMapListPreservesDuplicateSystemsAndDoesNotCertifyCompleteness()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var server=Task.Run(()=>Serve(pid,new{available=true,generation=9,total=3,entityId="42",items=new[]{"9007199254740993","9007199254740994","9007199254740993"}},stop.Token,
            r=>Check.Equal("galaxy.communitygoals",r.GetProperty("op").GetString())));
        var result=await new NativeGalaxyAccountCatalog(pid).ReadCommunityGoalsAsync(stop.Token);await server;
        Check.That(result.Available&&!result.Complete);Check.Equal(3,result.SystemAddresses.Count);Check.Equal(9007199254740993L,result.SystemAddresses[0]);Check.Equal(result.SystemAddresses[0],result.SystemAddresses[2]);
    }
    [Test] public async Task InvalidOriginalPowerIndexCannotSelectAnUnrelatedDefinition()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var server=Task.Run(()=>Serve(pid,new{available=true,optionsComplete=true,generation=9,total=1,entityId="42",items=new[]{
            new{index=0,uiPowerId=17,internalPowerId=17,name="Definition",rawRed=1f,rawGreen=0f,rawBlue=0f}}},stop.Token));
        var rejected=false;try{await new NativeGalaxyAccountCatalog(pid).ReadPowerOptionsAsync(stop.Token);}catch(InvalidDataException){rejected=true;}
        await server;Check.That(rejected);
    }
    [Test] public async Task SocialCachePreservesUnknownLocationCurrentAndIndependentSourceReadiness()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var server=Task.Run(()=>Serve(pid,new{available=true,generation=9,total=2,entityId="42",friendsReady=true,wingsReady=false,items=new[]{
            new{systemAddress="9007199254740993",kind="friend",status=0,statusName="offline",locationCurrent=(bool?)null},
            new{systemAddress="9007199254740994",kind="friend",status=6,statusName="open",locationCurrent=(bool?)true}}},stop.Token,r=>Check.Equal("galaxy.social",r.GetProperty("op").GetString())));
        var result=await new NativeGalaxyAccountCatalog(pid).ReadSocialAsync(stop.Token);await server;
        Check.That(result.Available&&result.FriendsReady&&!result.WingsReady&&!result.Complete);Check.Equal(2,result.Locations.Count);
        Check.Equal(9007199254740993L,result.Locations[0].SystemAddress);Check.That(result.Locations[0].LocationCurrent is null&&result.Locations[1].LocationCurrent==true);
    }
    [Test] public async Task SocialPagesCannotCrossOwnerOrSourceReadinessChanges()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        object Row()=>new{systemAddress="9007199254740993",kind="friend",status=6,statusName="open",locationCurrent=(bool?)null};
        var server=Task.Run(async()=>
        {
            await Serve(pid,new{available=true,generation=9,total=97,entityId="42",friendsReady=true,wingsReady=false,items=Enumerable.Range(0,96).Select(_=>Row())},stop.Token);
            await Serve(pid,new{available=true,generation=9,total=97,entityId="42",friendsReady=false,wingsReady=true,items=new[]{Row()}},stop.Token,
                r=>Check.Equal(96,r.GetProperty("offset").GetInt32()));
        });
        var rejected=false;try{await new NativeGalaxyAccountCatalog(pid).ReadSocialAsync(stop.Token);}catch(InvalidDataException){rejected=true;}
        await server;Check.That(rejected);
    }
    [Test] public async Task ColonisationCopiesExactCommanderAndStatusWithoutGuessingOwnershipOrAbsence()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var server=Task.Run(()=>Serve(pid,new{available=true,generation=9,total=2,entityId="42",items=new[]{
            new{systemAddress="9007199254740993",commanderId="9007199254740995",status=3,active=true},
            new{systemAddress="9007199254740994",commanderId="123",status=0,active=false}}},stop.Token,r=>Check.Equal("galaxy.colonisation",r.GetProperty("op").GetString())));
        var result=await new NativeGalaxyAccountCatalog(pid).ReadColonisationAsync(stop.Token);await server;
        Check.That(result.Available&&!result.Complete);Check.Equal(2,result.Claims.Count);
        Check.Equal(9007199254740995UL,result.Claims[0].CommanderId);Check.That(result.Claims[0].Active&&!result.Claims[1].Active);
        Check.Equal(9007199254740993L,result.Claims[0].SystemAddress);
    }
    [Test] public async Task ContradictoryColonisationStatusCannotBecomeAPersonalClaim()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var server=Task.Run(()=>Serve(pid,new{available=true,generation=9,total=1,entityId="42",items=new[]{
            new{systemAddress="9007199254740993",commanderId="123",status=0,active=true}}},stop.Token));
        var rejected=false;try{await new NativeGalaxyAccountCatalog(pid).ReadColonisationAsync(stop.Token);}catch(InvalidDataException){rejected=true;}
        await server;Check.That(rejected);
    }
    [Test] public async Task ExactLargeAddressesAndBothBookmarkSourcesSurviveStablePagination()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var server=Task.Run(async()=>
        {
            await Serve(pid,new{available=true,generation=7,total=17,entityId="42",items=Enumerable.Range(0,16).Select(Row)},stop.Token,
                r=>{Check.Equal("galaxy.account",r.GetProperty("op").GetString());Check.Equal(16,r.GetProperty("limit").GetInt32());});
            await Serve(pid,new{available=true,generation=7,total=17,entityId="42",items=new[]{Row(16)}},stop.Token,
                r=>{Check.Equal(7,r.GetProperty("generation").GetInt32());Check.Equal(16,r.GetProperty("offset").GetInt32());});
        });
        var result=await new NativeGalaxyAccountCatalog(pid).ReadAsync(stop.Token);await server;
        Check.That(result.Available&&!result.Complete);Check.Equal(17,result.Bookmarks.Count);Check.Equal(9007199254740993L,result.Bookmarks[0].SystemAddress);
        Check.That(!result.Bookmarks[0].Squadron&&result.Bookmarks[1].Squadron);
    }
    [Test] public async Task AChangedOwnerOrGenerationCannotMergeDifferentAccountSnapshots()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var server=Task.Run(async()=>
        {
            await Serve(pid,new{available=true,generation=8,total=17,entityId="42",items=Enumerable.Range(0,16).Select(Row)},stop.Token);
            await Serve(pid,new{available=true,generation=9,total=17,entityId="43",items=new[]{Row(16)}},stop.Token);
        });
        var rejected=false;try{await new NativeGalaxyAccountCatalog(pid).ReadAsync(stop.Token);}catch(InvalidDataException){rejected=true;}
        await server;Check.That(rejected);
    }
    [Test] public async Task UnavailableAndEmptySnapshotsCannotProveNoAccountBookmarksExist()
    {
        var pid=Random.Shared.Next(170000000,180000000);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(5));
        var server=Task.Run(()=>Serve(pid,new{available=false},stop.Token));var absent=await new NativeGalaxyAccountCatalog(pid).ReadAsync(stop.Token);await server;
        Check.That(!absent.Available&&!absent.Complete&&absent.Bookmarks.Count==0);
        server=Task.Run(()=>Serve(pid,new{available=true,generation=1,total=0,entityId="42",items=Array.Empty<object>()},stop.Token));
        var empty=await new NativeGalaxyAccountCatalog(pid).ReadAsync(stop.Token);await server;Check.That(empty.Available&&!empty.Complete&&empty.Bookmarks.Count==0);
    }
}