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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using XFEExtension.NetCore.XUnit.Attributes;
using XFEEDToolBox.Core.Execution;

namespace XFEEDToolBox.Test;

[TestFixture]
public class NativeCommunityGoalClientTests
{
    private sealed class Channel:IOriginalCommerceChannel
    {
        public string Identity=>"test-session";
        public int Reads,Polls,Refusals=2;
        public string? Failure;
        public bool CancelAfterRefusal;
        public CancellationTokenSource? Stop;
        public Task<JsonElement> CallAsync(object request,CancellationToken token)
        {
            token.ThrowIfCancellationRequested();var command=JsonSerializer.SerializeToElement(request);
            var op=command.GetProperty("op").GetString();
            if(op=="cg.read.mine")
            {
                Reads++;
                if(Failure is not null)throw new InvalidOperationException(Failure);
                if(Reads<=Refusals){if(CancelAfterRefusal)Stop!.Cancel();throw new InvalidOperationException("Fresh healthy docking at the requested CG market required");}
                return Task.FromResult(JsonSerializer.SerializeToElement(new{generation=17UL}));
            }
            if(op!="cg.status")throw new InvalidOperationException("Unexpected mutation or replay");
            Check.Equal(17UL,command.GetProperty("generation").GetUInt64());Polls++;
            if(Polls==1)throw new IOException("Transient status transport failure");
            const string body="{\"initiatives\":[]}";
            return Task.FromResult(JsonSerializer.SerializeToElement(new{state=3,kind=2,mutationsSent=0,fresh=true,responseBody=body,
                proof=Convert.ToHexStringLower(SHA256.HashData(Encoding.UTF8.GetBytes(body)))}));
        }
    }
    [Test] public async Task DockingTransitionWaitsThenPollsOnlyTheAcceptedRead()
    {
        var channel=new Channel();var result=await new NativeCommunityGoalClient(channel).ReadAsync(true);
        Check.Equal(3,channel.Reads);Check.Equal(2,channel.Polls);Check.Equal(17UL,result.Generation);Check.Equal(0,result.Goals.Count);
    }
    [Test] public async Task UnrelatedRefusalRemainsTerminal()
    {
        var channel=new Channel{Failure="Wrong game identity"};var rejected=false;
        try{await new NativeCommunityGoalClient(channel).ReadAsync(true);}catch(InvalidOperationException error){rejected=error.Message==channel.Failure;}
        Check.That(rejected);Check.Equal(1,channel.Reads);Check.Equal(0,channel.Polls);
    }
    [Test] public async Task CancellationDuringDockingWaitDoesNotQueueAnotherRequest()
    {
        using var stop=new CancellationTokenSource();var channel=new Channel{Stop=stop,CancelAfterRefusal=true};var cancelled=false;
        try{await new NativeCommunityGoalClient(channel).ReadAsync(true,stop.Token);}catch(OperationCanceledException){cancelled=true;}
        Check.That(cancelled);Check.Equal(1,channel.Reads);Check.Equal(0,channel.Polls);
    }
}