diff --git a/src/Aspire.Dashboard/Extensions/ResourceViewModelExtensions.cs b/src/Aspire.Dashboard/Extensions/ResourceViewModelExtensions.cs index d5ef389a857..625c9becfa9 100644 --- a/src/Aspire.Dashboard/Extensions/ResourceViewModelExtensions.cs +++ b/src/Aspire.Dashboard/Extensions/ResourceViewModelExtensions.cs @@ -22,6 +22,11 @@ public static bool IsFinishedState(this ResourceViewModel resource) return resource.KnownState is KnownResourceState.Finished; } + public static bool IsExitedState(this ResourceViewModel resource) + { + return resource.KnownState is KnownResourceState.Exited; + } + public static bool IsStopped(this ResourceViewModel resource) { return resource.KnownState is KnownResourceState.Exited or KnownResourceState.Finished or KnownResourceState.FailedToStart; diff --git a/src/Aspire.Dashboard/Model/ResourceStateViewModel.cs b/src/Aspire.Dashboard/Model/ResourceStateViewModel.cs index 02c51eaeb24..7882248f983 100644 --- a/src/Aspire.Dashboard/Model/ResourceStateViewModel.cs +++ b/src/Aspire.Dashboard/Model/ResourceStateViewModel.cs @@ -42,7 +42,7 @@ private static (Icon icon, Color color) GetStateIcon(ResourceViewModel resource) icon = new Icons.Filled.Size16.ErrorCircle(); color = Color.Error; } - else if (resource.IsFinishedState()) + else if (resource.IsFinishedState() || resource.IsExitedState()) { // Process completed successfully. icon = new Icons.Regular.Size16.RecordStop(); diff --git a/tests/Aspire.Dashboard.Tests/Model/ResourceStateViewModelTests.cs b/tests/Aspire.Dashboard.Tests/Model/ResourceStateViewModelTests.cs index f6475080a0d..2aba11ce4dc 100644 --- a/tests/Aspire.Dashboard.Tests/Model/ResourceStateViewModelTests.cs +++ b/tests/Aspire.Dashboard.Tests/Model/ResourceStateViewModelTests.cs @@ -15,45 +15,50 @@ namespace Aspire.Dashboard.Tests.Model; public class ResourceStateViewModelTests { - private const string ResourceType = "Container"; - [Theory] // Resource is no longer running [InlineData( - /* state */ KnownResourceState.Exited, null, null,null, - /* expected output */ $"Localized:{nameof(Columns.StateColumnResourceExited)}:{ResourceType}", "Warning", Color.Warning, "Exited")] + /* state */ "Container", KnownResourceState.Exited, null, null,null, + /* expected output */ $"Localized:{nameof(Columns.StateColumnResourceExited)}:Container", "RecordStop", Color.Info, "Exited")] + [InlineData( + /* state */ "Container", KnownResourceState.Exited, 3, null, null, + /* expected output */ $"Localized:{nameof(Columns.StateColumnResourceExitedUnexpectedly)}:Container+3", "ErrorCircle", Color.Error, "Exited")] + [InlineData( + /* state */ "Container", KnownResourceState.Exited, 0, null, null, + /* expected output */ $"Localized:{nameof(Columns.StateColumnResourceExited)}:Container", "RecordStop", Color.Info, "Exited")] [InlineData( - /* state */ KnownResourceState.Exited, 3, null, null, - /* expected output */ $"Localized:{nameof(Columns.StateColumnResourceExitedUnexpectedly)}:{ResourceType}+3", "ErrorCircle", Color.Error, "Exited")] + /* state */ "Container", KnownResourceState.Finished, 0, null, null, + /* expected output */ $"Localized:{nameof(Columns.StateColumnResourceExited)}:Container", "RecordStop", Color.Info, "Finished")] [InlineData( - /* state */ KnownResourceState.Finished, 0, null, null, - /* expected output */ $"Localized:{nameof(Columns.StateColumnResourceExited)}:{ResourceType}", "RecordStop", Color.Info, "Finished")] + /* state */ "CustomResource", KnownResourceState.Finished, null, null, null, + /* expected output */ $"Localized:{nameof(Columns.StateColumnResourceExited)}:CustomResource", "RecordStop", Color.Info, "Finished")] [InlineData( - /* state */ KnownResourceState.Unknown, null, null, null, + /* state */ "Container", KnownResourceState.Unknown, null, null, null, /* expected output */ "Unknown", "CircleHint", Color.Info, "Unknown")] // Health checks [InlineData( - /* state */ KnownResourceState.Running, null, "Healthy", null, + /* state */ "Container", KnownResourceState.Running, null, "Healthy", null, /* expected output */ "Running", "CheckmarkCircle", Color.Success, "Running")] [InlineData( - /* state */ KnownResourceState.Running, null, "", null, + /* state */ "Container", KnownResourceState.Running, null, "", null, /* expected output */ $"Localized:{nameof(Columns.RunningAndUnhealthyResourceStateToolTip)}", "CheckmarkCircleWarning", Color.Warning, "Running (Unhealthy)")] [InlineData( - /* state */ KnownResourceState.Running, null, "Unhealthy", null, + /* state */ "Container", KnownResourceState.Running, null, "Unhealthy", null, /* expected output */ $"Localized:{nameof(Columns.RunningAndUnhealthyResourceStateToolTip)}", "CheckmarkCircleWarning", Color.Warning, "Running (Unhealthy)")] [InlineData( - /* state */ KnownResourceState.Running, null, "Healthy", "warning", + /* state */ "Container", KnownResourceState.Running, null, "Healthy", "warning", /* expected output */ "Running", "Warning", Color.Warning, "Running")] [InlineData( - /* state */ KnownResourceState.Running, null, "Healthy", "NOT_A_VALID_STATE_STYLE", + /* state */ "Container", KnownResourceState.Running, null, "Healthy", "NOT_A_VALID_STATE_STYLE", /* expected output */ "Running", "Circle", Color.Neutral, "Running")] [InlineData( - /* state */ KnownResourceState.Running, null, null, "info", + /* state */ "Container", KnownResourceState.Running, null, null, "info", /* expected output */ "Running", "Info", Color.Info, "Running")] [InlineData( - /* state */ KnownResourceState.RuntimeUnhealthy, null, null, null, + /* state */ "Container", KnownResourceState.RuntimeUnhealthy, null, null, null, /* expected output */ $"Localized:{nameof(Columns.StateColumnResourceContainerRuntimeUnhealthy)}", "Warning", Color.Warning, "Runtime unhealthy")] public void ResourceViewModel_ReturnsCorrectIconAndTooltip( + string resourceType, KnownResourceState state, int? exitCode, string? healthStatusString, @@ -76,7 +81,7 @@ public void ResourceViewModel_ReturnsCorrectIconAndTooltip( reportHealthStatus: healthStatus, createNullHealthReport: healthStatusString == "", stateStyle: stateStyle, - resourceType: ResourceType, + resourceType: resourceType, properties: propertiesDictionary); if (exitCode is not null)