diff --git a/ILSpy.Tests/Updates/UpdatePanelViewModelTests.cs b/ILSpy.Tests/Updates/UpdatePanelViewModelTests.cs new file mode 100644 index 000000000..5c67da42c --- /dev/null +++ b/ILSpy.Tests/Updates/UpdatePanelViewModelTests.cs @@ -0,0 +1,67 @@ +// Copyright (c) 2026 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System.Collections.Generic; +using System.ComponentModel; + +using Avalonia.Headless.NUnit; + +using AwesomeAssertions; + +using ILSpy.AppEnv; +using ILSpy.ViewModels; + +using NUnit.Framework; + +namespace ICSharpCode.ILSpy.Tests.Updates; + +/// +/// The update banner colours itself by state: green when ILSpy is up to date, amber when an +/// update is available. is the boolean that +/// drives that (bound to a style class in the view), so pin that it tracks the download URL. +/// +[TestFixture] +public class UpdatePanelViewModelTests +{ + [AvaloniaTest] + public void UpdateAvailable_tracks_the_download_url() + { + var vm = AppComposition.Current.GetExport(); + + vm.UpdateAvailableDownloadUrl = null; + vm.UpdateAvailable.Should().BeFalse("no download URL means ILSpy is up to date"); + + vm.UpdateAvailableDownloadUrl = "https://example.invalid/ILSpy.zip"; + vm.UpdateAvailable.Should().BeTrue("a download URL means an update is available"); + } + + [AvaloniaTest] + public void Setting_the_download_url_notifies_UpdateAvailable() + { + var vm = AppComposition.Current.GetExport(); + vm.UpdateAvailableDownloadUrl = null; + + var changed = new List(); + vm.PropertyChanged += (_, e) => changed.Add(e.PropertyName); + + vm.UpdateAvailableDownloadUrl = "https://example.invalid/ILSpy.zip"; + + changed.Should().Contain(nameof(UpdatePanelViewModel.UpdateAvailable), + "the banner colour binds to UpdateAvailable, so it must raise PropertyChanged for it"); + } +} diff --git a/ILSpy/ViewModels/UpdatePanelViewModel.cs b/ILSpy/ViewModels/UpdatePanelViewModel.cs index 167215f67..beebd9dff 100644 --- a/ILSpy/ViewModels/UpdatePanelViewModel.cs +++ b/ILSpy/ViewModels/UpdatePanelViewModel.cs @@ -51,6 +51,7 @@ namespace ILSpy.ViewModels [ObservableProperty] [NotifyPropertyChangedFor(nameof(ButtonText))] [NotifyPropertyChangedFor(nameof(Message))] + [NotifyPropertyChangedFor(nameof(UpdateAvailable))] string? updateAvailableDownloadUrl; [ObservableProperty] @@ -64,6 +65,10 @@ namespace ILSpy.ViewModels ? "A new version of ILSpy is available." : "ILSpy is up to date."; + /// True once a download URL is known. Drives the banner colour: amber when an + /// update is available, green when ILSpy is up to date. + public bool UpdateAvailable => UpdateAvailableDownloadUrl != null; + [RelayCommand] void Close() => IsPanelVisible = false; diff --git a/ILSpy/Views/UpdatePanel.axaml b/ILSpy/Views/UpdatePanel.axaml index 61005a08f..4ea39a45d 100644 --- a/ILSpy/Views/UpdatePanel.axaml +++ b/ILSpy/Views/UpdatePanel.axaml @@ -4,9 +4,25 @@ x:Class="ILSpy.Views.UpdatePanel" x:DataType="vm:UpdatePanelViewModel" IsVisible="{Binding IsPanelVisible}"> - + + + + + + - + +