using Microsoft.Extensions.DependencyInjection; using Orleans.Hosting; using Orleans.TestingHost; using Vanguard.Rules.Engine; using Vanguard.Server.Configuration; using Vanguard.Server.Matches; using Vanguard.Server.Matches.Orleans; using Vanguard.Server.Storage; using Vanguard.Shared.Protocol; namespace Vanguard.Server.Tests; [Collection("Orleans")] public class OrleansMatchTests { [Fact] public async Task Grain_Initializes_Attaches_And_Submits_Intent() { var connections = new MatchConnectionRegistry(); var results = new RecordingResultSink(); var builder = new TestClusterBuilder(); SiloConfigurator.Set(connections, results); builder.AddSiloBuilderConfigurator(); var cluster = builder.Build(); try { await cluster.DeployAsync(); var actor = cluster.Client.GetGrain("orleans-match"); var setup = new MatchSetup( "orleans-match", GameMode.ClassicRanked, new MatchSeatSetup("p1", ServerTestData.BuildDeck(), 1000), new MatchSeatSetup("p2", ServerTestData.BuildDeck(), 1000)); await actor.InitializeAsync(MatchSetupData.From(setup)); var first = new FakeMatchConnection(); connections.Register("orleans-match", 0, first); Assert.True(await actor.AttachAsync(0, "p1", 0)); var hello = first.All().Single(); Assert.Equal(0, hello.PlayerIndex); Assert.False(hello.Resumed); var snapshot = first.All().Single().View; Assert.Equal(5, snapshot.Players[0].Hand.Count); Assert.Empty(snapshot.Players[1].Hand); var summary = await actor.GetSummaryAsync(); var intent = new ClientIntent { IntentId = "orleans-intent-1", BasedOnSeq = summary.EventSeq, Intent = new FinishMulliganIntent(), }; await actor.SubmitAsync(0, ProtocolSerializer.Encode(intent)); var accepted = first.Last(); Assert.True(accepted.Accepted); var after = await actor.GetSummaryAsync(); Assert.True(after.EventSeq >= summary.EventSeq); Assert.True(await actor.HasPlayerAsync("p1")); Assert.False(await actor.HasPlayerAsync("stranger")); } finally { await cluster.DisposeAsync(); } } private sealed class SiloConfigurator : ISiloConfigurator { private static IMatchConnectionRegistry _connections = null!; private static IMatchResultSink _results = null!; public static void Set( IMatchConnectionRegistry connections, IMatchResultSink results) { _connections = connections; _results = results; } public void Configure(ISiloBuilder siloBuilder) { siloBuilder.ConfigureServices(services => { var options = ServerTestData.SmallOptions(); services.AddSingleton(ServerTestData.Catalog); services.AddSingleton(options); services.AddSingleton(TimeProvider.System); services.AddSingleton(_results); services.AddSingleton(); services.AddSingleton(_connections); services.AddLogging(); }); } } }