Skip to content

Commit 9f22d2e

Browse files
authored
Fix restart prompt when loading text settings (#5508)
Co-authored-by: raven <248401188+r4venrudy@users.noreply.github.com>
1 parent e309122 commit 9f22d2e

3 files changed

Lines changed: 109 additions & 0 deletions

File tree

‎src/UniGetUI.Avalonia/Views/Controls/Settings/TextboxCard.cs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ public void SaveValue()
110110
if (CoreSettings.ResolveKey(setting_name).Contains("File"))
111111
sanitizedText = CoreTools.MakeValidFileName(sanitizedText);
112112

113+
// TextChanged is queued, so loading a setting can reach this handler too.
114+
if (sanitizedText == CoreSettings.GetValue(setting_name))
115+
return;
116+
113117
if (sanitizedText != "")
114118
CoreSettings.SetValue(setting_name, sanitizedText);
115119
else
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using Avalonia;
2+
using Avalonia.Controls;
3+
using Avalonia.Headless;
4+
using Avalonia.Threading;
5+
using CommunityToolkit.Mvvm.Input;
6+
using UniGetUI.Avalonia.Views.Controls.Settings;
7+
using UniGetUI.Core.Data;
8+
using CoreSettings = UniGetUI.Core.SettingsEngine.Settings;
9+
10+
namespace UniGetUI.Tests;
11+
12+
public sealed class TextboxCardTests : IDisposable
13+
{
14+
private readonly HeadlessUnitTestSession _session = HeadlessUnitTestSession.StartNew(typeof(Application));
15+
private readonly string _testRoot = Path.Combine(Path.GetTempPath(), nameof(TextboxCardTests), Guid.NewGuid().ToString("N"));
16+
17+
public TextboxCardTests()
18+
{
19+
CoreData.TEST_DataDirectoryOverride = Path.Combine(_testRoot, "Data");
20+
Directory.CreateDirectory(CoreData.UniGetUIUserConfigurationDirectory);
21+
CoreSettings.ResetSettings();
22+
}
23+
24+
public void Dispose()
25+
{
26+
_session.Dispose();
27+
CoreSettings.ResetSettings();
28+
CoreData.TEST_DataDirectoryOverride = null;
29+
Directory.Delete(_testRoot, recursive: true);
30+
}
31+
32+
[Theory]
33+
[InlineData("")]
34+
[InlineData("https://example.com/icons.json")]
35+
public Task LoadingSavedValueDoesNotNotify(string savedValue) => _session.Dispatch(() =>
36+
{
37+
CoreSettings.SetValue(CoreSettings.K.IconDataBaseURL, savedValue);
38+
int events = 0;
39+
int commands = 0;
40+
var card = new TextboxCard
41+
{
42+
ValueChangedCommand = new RelayCommand(() => commands++),
43+
};
44+
card.ValueChanged += (_, _) => events++;
45+
card.SettingName = CoreSettings.K.IconDataBaseURL;
46+
47+
// Avalonia posts TextChanged, so loading the value can reach handlers attached afterwards.
48+
Dispatcher.UIThread.RunJobs();
49+
50+
Assert.Equal(0, events);
51+
Assert.Equal(0, commands);
52+
Assert.Equal(savedValue, CoreSettings.GetValue(CoreSettings.K.IconDataBaseURL));
53+
}, CancellationToken.None);
54+
55+
[Fact]
56+
public Task EditingAndClearingValueSavesAndNotifiesOncePerChange() => _session.Dispatch(() =>
57+
{
58+
var card = new TextboxCard { SettingName = CoreSettings.K.IconDataBaseURL };
59+
Dispatcher.UIThread.RunJobs();
60+
int events = 0;
61+
int commands = 0;
62+
card.ValueChanged += (_, _) => events++;
63+
card.ValueChangedCommand = new RelayCommand(() => commands++);
64+
TextBox textBox = Assert.Single(Assert.IsType<StackPanel>(card.Content).Children.OfType<TextBox>());
65+
66+
textBox.Text = "https://example.com/icons.json";
67+
Dispatcher.UIThread.RunJobs();
68+
card.SaveValue();
69+
70+
Assert.Equal(textBox.Text, CoreSettings.GetValue(CoreSettings.K.IconDataBaseURL));
71+
Assert.Equal(1, events);
72+
Assert.Equal(1, commands);
73+
74+
textBox.Text = "";
75+
Dispatcher.UIThread.RunJobs();
76+
card.SaveValue();
77+
78+
Assert.Equal("", CoreSettings.GetValue(CoreSettings.K.IconDataBaseURL));
79+
Assert.False(CoreSettings.Get(CoreSettings.K.IconDataBaseURL));
80+
Assert.Equal(2, events);
81+
Assert.Equal(2, commands);
82+
}, CancellationToken.None);
83+
84+
[Fact]
85+
public Task NumericFilteringNotifiesOnlyWhenSanitizedValueChanges() => _session.Dispatch(() =>
86+
{
87+
CoreSettings.SetValue(CoreSettings.K.IconDataBaseURL, "12");
88+
var card = new TextboxCard { SettingName = CoreSettings.K.IconDataBaseURL, IsNumericOnly = true };
89+
Dispatcher.UIThread.RunJobs();
90+
int changes = 0;
91+
card.ValueChanged += (_, _) => changes++;
92+
TextBox textBox = Assert.Single(Assert.IsType<StackPanel>(card.Content).Children.OfType<TextBox>());
93+
94+
textBox.Text = "1a2";
95+
Dispatcher.UIThread.RunJobs();
96+
Assert.Equal("12", textBox.Text);
97+
Assert.Equal(0, changes);
98+
99+
textBox.Text = "3a4";
100+
Dispatcher.UIThread.RunJobs();
101+
Assert.Equal("34", CoreSettings.GetValue(CoreSettings.K.IconDataBaseURL));
102+
Assert.Equal(1, changes);
103+
}, CancellationToken.None);
104+
}

‎src/UniGetUI.Tests/UniGetUI.Tests.csproj‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
</PropertyGroup>
1414

1515
<ItemGroup>
16+
<PackageReference Include="Avalonia.Headless" Version="12.0.4" />
1617
<PackageReference Include="coverlet.collector" Version="6.0.4">
1718
<PrivateAssets>all</PrivateAssets>
1819
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

0 commit comments

Comments
 (0)