| File: Layout\MainLayoutResourceTerminalsTests.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 System.Threading.Channels; using Aspire.Dashboard.Components.Controls; using Aspire.Dashboard.Components.Layout; using Aspire.Dashboard.Components.Resize; using Aspire.Dashboard.Components.Tests.Shared; using Aspire.Dashboard.Tests.Shared; using Aspire.Tests.Shared.DashboardModel; using Bunit; using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Aspire.Dashboard.Components.Tests.Layout; public partial class MainLayoutTests { [Theory] [InlineData(true)] [InlineData(false)] public async Task ResourceTerminalsNavigation_RunSwitchCancelsAndRestartsAvailabilityWatch(bool isDesktop) { var disposed = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var client = new TestDashboardClient(isEnabled: true, initialResources: [TerminalSetupHelpers.CreateTerminalResource("shell")], resourceChannelProvider: () => Channel.CreateUnbounded<IReadOnlyList<ResourceViewModelChange>>()) { OnResourceSubscriptionDisposed = () => disposed.TrySetResult() }; var runStore = new FluentUISetupHelpers.TestDashboardRunStore( [ new("current", DashboardRunStore.SchemaVersion, DateTimeOffset.UnixEpoch, null, false, "TestApp", string.Empty, true), new("historical", DashboardRunStore.SchemaVersion, DateTimeOffset.UnixEpoch, DateTimeOffset.UnixEpoch, true, "TestApp", string.Empty, false) ]); SetupMainLayoutServices(dashboardRunStore: runStore, dashboardClient: client); var selection = Assert.IsType<FluentUISetupHelpers.TestDashboardRunSelection>(Services.GetRequiredService<IDashboardRunSelection>()); selection.OnSelectRun = runId => client.IsReadOnly = runId is not null; var cut = Render<MainLayout>(builder => builder.Add(p => p.ViewportInformation, new ViewportInformation(IsDesktop: isDesktop, IsUltraLowHeight: false, IsUltraLowWidth: false))); cut.WaitForAssertion(() => Assert.True(HasTerminals())); Assert.Equal(1, client.ResourceSubscriptionCount); await cut.InvokeAsync(() => cut.FindComponent<DashboardRunSelect>().Instance.SelectedRunIdChanged.InvokeAsync("historical")); await disposed.Task.WaitAsync(DefaultWaitTimeout); Assert.False(HasTerminals()); Assert.Empty(cut.FindComponents<ResourceTerminalsAvailabilityProvider>()); await cut.InvokeAsync(() => cut.FindComponent<DashboardRunSelect>().Instance.SelectedRunIdChanged.InvokeAsync(null)); cut.WaitForAssertion(() => Assert.True(HasTerminals())); Assert.Equal(2, client.ResourceSubscriptionCount); bool HasTerminals() => isDesktop ? cut.FindComponent<DesktopNavMenu>().Instance.HasResourceTerminals : cut.FindComponent<MobileNavMenu>().Instance.HasResourceTerminals; } [Theory] [InlineData(true, false)] [InlineData(false, false)] [InlineData(true, true)] [InlineData(false, true)] public async Task ResourceTerminalsNavigation_TracksCapabilitiesIncludingHiddenResources(bool isDesktop, bool hidden) { var updates = Channel.CreateUnbounded<IReadOnlyList<ResourceViewModelChange>>(); var client = new TestDashboardClient(isEnabled: true, resourceChannelProvider: () => updates); SetupMainLayoutServices(dashboardClient: client); var cut = Render<MainLayout>(builder => builder.Add(p => p.ViewportInformation, new ViewportInformation(IsDesktop: isDesktop, IsUltraLowHeight: false, IsUltraLowWidth: false))); if (!isDesktop) { await cut.InvokeAsync(() => cut.Find($"#{MainLayout.NavigationButtonId}").Click()); } AssertNavigation(false); var resource = TerminalSetupHelpers.CreateTerminalResource("shell", hidden: hidden); await updates.Writer.WriteAsync([new(ResourceViewModelChangeType.Upsert, resource)]); cut.WaitForAssertion(() => AssertNavigation(true)); await updates.Writer.WriteAsync([new(ResourceViewModelChangeType.Upsert, ModelTestHelpers.CreateResource("shell"))]); cut.WaitForAssertion(() => AssertNavigation(false)); await updates.Writer.WriteAsync([new(ResourceViewModelChangeType.Upsert, resource)]); cut.WaitForAssertion(() => AssertNavigation(true)); await updates.Writer.WriteAsync([new(ResourceViewModelChangeType.Delete, resource)]); cut.WaitForAssertion(() => AssertNavigation(false)); void AssertNavigation(bool expected) { if (isDesktop) { Assert.Equal(expected, cut.FindComponent<DesktopNavMenu>().Instance.HasResourceTerminals); } else { Assert.Equal(expected, cut.FindComponent<MobileNavMenu>().Instance.HasResourceTerminals); } } } }