using Microsoft.JSInterop; using RpgRoller.Components; using RpgRoller.Components.Pages; namespace RpgRoller.Tests; public sealed class WorkspaceCampaignCoordinatorTests { [Fact] public async Task OnCampaignCreatedAsync_RequestsRefreshAfterReloadingWorkspaceState() { var calls = new List(); var coordinator = CreateCoordinator( reloadCampaignsAsync: campaignId => { calls.Add($"reloadCampaigns:{campaignId:D}"); return Task.CompletedTask; }, reloadCharacterCampaignOptionsAsync: () => { calls.Add("reloadCharacterCampaignOptions"); return Task.CompletedTask; }, refreshCampaignScopeAsync: () => { calls.Add("refreshCampaignScope"); return Task.CompletedTask; }, syncStateEventsAsync: () => { calls.Add("syncStateEvents"); return Task.CompletedTask; }, requestRefreshAsync: () => { calls.Add("requestRefresh"); return Task.CompletedTask; }); var campaignId = Guid.NewGuid(); await coordinator.OnCampaignCreatedAsync(campaignId); Assert.Equal([ $"reloadCampaigns:{campaignId:D}", "reloadCharacterCampaignOptions", "refreshCampaignScope", "syncStateEvents", "requestRefresh" ], calls); } [Fact] public async Task OnCharacterCreatedAsync_RequestsRefreshAfterReloadingWorkspaceState() { var calls = new List(); var coordinator = CreateCoordinator( reloadCampaignsAsync: campaignId => { calls.Add($"reloadCampaigns:{campaignId:D}"); return Task.CompletedTask; }, reloadCharacterCampaignOptionsAsync: () => { calls.Add("reloadCharacterCampaignOptions"); return Task.CompletedTask; }, refreshCampaignScopeAsync: () => { calls.Add("refreshCampaignScope"); return Task.CompletedTask; }, syncStateEventsAsync: () => { calls.Add("syncStateEvents"); return Task.CompletedTask; }, requestRefreshAsync: () => { calls.Add("requestRefresh"); return Task.CompletedTask; }); var campaignId = Guid.NewGuid(); await coordinator.OnCharacterCreatedAsync(campaignId); Assert.Equal([ $"reloadCampaigns:{campaignId:D}", "reloadCharacterCampaignOptions", "refreshCampaignScope", "syncStateEvents", "requestRefresh" ], calls); } [Fact] public async Task OnCharacterUpdatedAsync_RequestsRefreshAfterReloadingWorkspaceState() { var calls = new List(); var coordinator = CreateCoordinator( reloadCampaignsAsync: campaignId => { calls.Add($"reloadCampaigns:{campaignId:D}"); return Task.CompletedTask; }, reloadCharacterCampaignOptionsAsync: () => { calls.Add("reloadCharacterCampaignOptions"); return Task.CompletedTask; }, refreshCampaignScopeAsync: () => { calls.Add("refreshCampaignScope"); return Task.CompletedTask; }, syncStateEventsAsync: () => { calls.Add("syncStateEvents"); return Task.CompletedTask; }, requestRefreshAsync: () => { calls.Add("requestRefresh"); return Task.CompletedTask; }); var campaignId = Guid.NewGuid(); await coordinator.OnCharacterUpdatedAsync(campaignId); Assert.Equal([ $"reloadCampaigns:{campaignId:D}", "reloadCharacterCampaignOptions", "refreshCampaignScope", "syncStateEvents", "requestRefresh" ], calls); } private static WorkspaceCampaignCoordinator CreateCoordinator( Func? reloadCampaignsAsync = null, Func? reloadCharacterCampaignOptionsAsync = null, Func? refreshCampaignScopeAsync = null, Func? syncStateEventsAsync = null, Func? requestRefreshAsync = null) { var state = new WorkspaceState(); var feedback = new WorkspaceFeedbackService(state, () => Task.CompletedTask); return new WorkspaceCampaignCoordinator( state, feedback, new StubJsRuntime(), new RpgRollerApiClient(new StubJsRuntime()), () => Task.CompletedTask, reloadCampaignsAsync ?? (_ => Task.CompletedTask), reloadCharacterCampaignOptionsAsync ?? (() => Task.CompletedTask), refreshCampaignScopeAsync ?? (() => Task.CompletedTask), syncStateEventsAsync ?? (() => Task.CompletedTask), requestRefreshAsync ?? (() => Task.CompletedTask)); } private sealed class StubJsRuntime : IJSRuntime { public ValueTask InvokeAsync(string identifier, object?[]? args) { return ValueTask.FromResult(default(TValue)!); } public ValueTask InvokeAsync(string identifier, CancellationToken cancellationToken, object?[]? args) { return InvokeAsync(identifier, args); } } }