| File: Model\DashboardDialogServiceTests.cs | Web Access |
| Project: src\tests\Aspire.Dashboard.Components.Tests\Aspire.Dashboard.Components.Tests.csproj (Aspire.Dashboard.Components.Tests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Aspire.Dashboard.Components.Dialogs; using Aspire.Dashboard.Components.Resize; using Aspire.Dashboard.Model; using Aspire.Dashboard.Model.Interaction; using Aspire.Dashboard.Tests; using Aspire.Tests.Shared; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.InternalTesting; using Microsoft.FluentUI.AspNetCore.Components; using Xunit; namespace Aspire.Dashboard.Components.Tests.Model; public class DashboardDialogServiceTests { [Fact] public async Task WaitForData_AlreadyAvailable_DoesNotShowDialog() { var dialogService = CreateDialogService(out var innerDialogService); Assert.True(await WaitForDataAsync(_ => Task.FromResult(true), dialogService).DefaultTimeout()); Assert.Null(innerDialogService.LastInstance); } [Theory] [InlineData(false)] [InlineData(true)] public async Task WaitForData_Canceled_DoesNotNavigate(bool dismiss) { var dialogService = CreateDialogService(out var innerDialogService); var waitTask = WaitForDataAsync(_ => Task.FromResult(false), dialogService); var instance = Assert.IsType<DialogInstance>(innerDialogService.LastInstance); var content = Assert.IsType<InteractionsProgressDialogViewModel>(instance.Options.Parameters["Content"]); Assert.Equal("Waiting for trace data", content.Message); var loc = new TestStringLocalizer<Aspire.Dashboard.Resources.Dialogs>(); Assert.Equal(loc[nameof(Aspire.Dashboard.Resources.Dialogs.OpenSpanDialogCancelButtonText)].Value, instance.Options.Footer.PrimaryAction.Label); Assert.False(instance.Options.Footer.PrimaryAction.Visible); Assert.Null(instance.Options.Footer.SecondaryAction.Label); await instance.CloseAsync(dismiss ? DialogResult.Cancel() : DialogResult.Ok("cancel")); Assert.False(await waitTask.DefaultTimeout()); } [Fact] public async Task WaitForData_BecomesAvailable_ClosesProgressDialog() { var dialogService = CreateDialogService(out var innerDialogService); var dataAvailable = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously); var callbackCount = 0; var waitTask = WaitForDataAsync( _ => Interlocked.Increment(ref callbackCount) == 1 ? Task.FromResult(false) : dataAvailable.Task, dialogService); Assert.NotNull(innerDialogService.LastInstance); dataAvailable.SetResult(true); Assert.True(await waitTask.DefaultTimeout()); var result = await innerDialogService.LastInstance.Result.DefaultTimeout(); Assert.False(result.Cancelled); Assert.Equal(true, result.Value); } private static Task<bool> WaitForDataAsync(Func<CancellationToken, Task<bool>> isAvailable, DashboardDialogService dialogService) { return TraceLinkHelpers.WaitForDataToBeAvailableAsync( isAvailable, "Waiting for trace data", dialogService, callback => callback(), new TestStringLocalizer<Aspire.Dashboard.Resources.Dialogs>(), CancellationToken.None); } [Theory] [InlineData(false)] [InlineData(true)] public async Task CloseAsync_WaitsForClosingAndResultCallbacks(bool withResult) { var dialogService = CreateDialogService(out _); var closingStarted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var allowClosing = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var resultStarted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var allowResult = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var reference = await dialogService.ShowDialogAsync<HelpDialog>(new DialogParameters { OnDialogClosing = EventCallback.Factory.Create<IDialogInstance>(this, async _ => { closingStarted.SetResult(); await allowClosing.Task; }), OnDialogResult = EventCallback.Factory.Create<DialogResult>(this, async _ => { resultStarted.SetResult(); await allowResult.Task; }) }); var closeTask = withResult ? reference.CloseAsync(DialogResult.Ok(true)) : reference.CloseAsync(); try { await closingStarted.Task.DefaultTimeout(); Assert.False(closeTask.IsCompleted); allowClosing.SetResult(); await resultStarted.Task.DefaultTimeout(); Assert.False(closeTask.IsCompleted); allowResult.SetResult(); await closeTask.DefaultTimeout(); Assert.True(reference.Result.IsCompletedSuccessfully); Assert.Equal(withResult ? true : null, (await reference.Result).Value); } finally { allowClosing.TrySetResult(); allowResult.TrySetResult(); } } [Theory] [InlineData(false, false)] [InlineData(true, true)] public async Task ShowDialog_MapsOverlayDismissBehavior(bool preventDismissOnOverlayClick, bool expectedModal) { var dialogService = CreateDialogService(out var innerDialogService); var reference = await dialogService.ShowDialogAsync<HelpDialog>(new DialogParameters { PreventDismissOnOverlayClick = preventDismissOnOverlayClick }); Assert.Equal(expectedModal, innerDialogService.LastInstance!.Options.Modal); await reference.CloseAsync(); } [Theory] [InlineData(false)] [InlineData(true)] public async Task ShowPanel_PreservesModalBehavior(bool modal) { var dialogService = CreateDialogService(out var innerDialogService); var reference = await dialogService.ShowPanelAsync<HelpDialog>(new DialogParameters { Modal = modal }); Assert.Equal(modal, innerDialogService.LastInstance!.Options.Modal); await reference.CloseAsync(); } private static DashboardDialogService CreateDialogService(out TestDialogService innerDialogService) { innerDialogService = new TestDialogService(); var dimensionManager = new DimensionManager(); dimensionManager.InvokeOnViewportInformationChanged(new ViewportInformation(IsDesktop: true, IsUltraLowHeight: false, IsUltraLowWidth: false)); return new DashboardDialogService( innerDialogService, new TestStringLocalizer<Aspire.Dashboard.Resources.Dialogs>(), dimensionManager); } }