using Avalonia.Controls; using Avalonia.Headless.XUnit; using Avalonia.Threading; using Avalonia.VisualTree; using AvParser.Core.Proxies; using AvParser.UI.ViewModels; using AvParser.UI.Views; using Microsoft.Extensions.Logging.Abstractions; using ReactiveUI.Primitives.Concurrency; namespace AvParser.UI.HeadlessTests; public class ProxiesViewTests { private static (ProxiesView View, ProxiesViewModel ViewModel, Window Window) ShowPage( params ProxyEndpoint[] endpoints ) { var custom = new FakeMutableProxySource(); custom.Endpoints.AddRange(endpoints); var pool = new ProxyPool([custom], new FakeProxyProbe(), new ProxyOptions()); var viewModel = new ProxiesViewModel( pool, custom, NullLogger.Instance, ImmediateSequencer.Instance ); var view = new ProxiesView { DataContext = viewModel }; var window = new Window { Width = 1400, Height = 800, Content = view, }; window.Show(); Dispatcher.UIThread.RunJobs(); return (view, viewModel, window); } [AvaloniaFact] public void The_page_renders_with_an_empty_pool() { var (view, _, _) = ShowPage(); view.GetVisualDescendants().OfType().ShouldNotBeEmpty(); } [AvaloniaFact] public async Task Refreshing_puts_rows_on_screen() { var (view, viewModel, _) = ShowPage( new ProxyEndpoint(ProxyProtocol.Socks5, "10.0.0.1", 1080), new ProxyEndpoint(ProxyProtocol.Http, "10.0.0.2", 8080) ); await viewModel.RefreshCommand.Execute().ToTask(TestContext.Current.CancellationToken); Dispatcher.UIThread.RunJobs(); var list = view.GetVisualDescendants().OfType().First(); list.ItemCount.ShouldBe(2); viewModel.TotalCount.ShouldBe(2); } [AvaloniaFact] public async Task Rows_carry_the_address_and_the_source() { var (_, viewModel, _) = ShowPage(new ProxyEndpoint(ProxyProtocol.Socks5, "10.0.0.1", 1080)); await viewModel.RefreshCommand.Execute().ToTask(TestContext.Current.CancellationToken); Dispatcher.UIThread.RunJobs(); var row = viewModel.Proxies.ShouldHaveSingleItem(); row.Address.ShouldBe("socks5://10.0.0.1:1080"); row.Source.ShouldBe("custom"); row.HealthText.ShouldBe("unchecked"); } }