Public Access
Give the window its v5b chrome and each session surface its own shell
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Headless;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.VisualTree;
|
||||
using DodoSSH.Client.App.Views;
|
||||
using DodoSSH.Client.Session;
|
||||
using DodoSSH.Client.Shell.ViewModels;
|
||||
using DodoSSH.Client.Ssh;
|
||||
using DodoSSH.Client.Storage;
|
||||
using DodoSSH.Client.Terminal;
|
||||
using NSubstitute;
|
||||
|
||||
namespace DodoSSH.Client.App.Layout.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// The titlebar's own search pill still opens the quick-connect palette after v5b's redraw.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A narrow suite on purpose: <see cref="LayoutHarnessTests"/> already holds the bar to its declared
|
||||
/// height and proves nothing inside it is unreachable, and the search pill's own accent-on-hover border is
|
||||
/// a style rule with nothing to assert headlessly. What is worth a gesture is the one thing a fidelity pass
|
||||
/// could quietly break without any layout test noticing — the pill no longer opening what Ctrl+K opens.
|
||||
/// </remarks>
|
||||
public sealed class TitleBarTests : IAsyncLifetime
|
||||
{
|
||||
private ClientCacheFactory caches = null!;
|
||||
private TerminalWorkspace workspace = null!;
|
||||
private MainWindowViewModel shell = null!;
|
||||
|
||||
private static CancellationToken Token => TestContext.Current.CancellationToken;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValueTask InitializeAsync()
|
||||
{
|
||||
caches = ClientCacheFactory.ForMemory($"titlebar-{Guid.CreateVersion7():N}");
|
||||
|
||||
workspace = new TerminalWorkspace(
|
||||
new InMemoryTerminalAssetProvider(new Dictionary<string, TerminalAsset>(StringComparer.Ordinal)),
|
||||
Substitute.For<ISshConnectionFactory>(),
|
||||
TimeProvider.System);
|
||||
|
||||
shell = new MainWindowViewModel(
|
||||
ClientPaths.Default,
|
||||
caches,
|
||||
workspace,
|
||||
new VaultKnownHostStore(),
|
||||
Substitute.For<IDeviceKeyStore>(),
|
||||
(_, _) => throw new NotSupportedException("nothing here signs in"),
|
||||
TimeProvider.System,
|
||||
Substitute.For<ISftpSessionFactory>())
|
||||
{
|
||||
// The search pill is disabled while locked — see TitleBar.axaml's IsEnabled binding — and this
|
||||
// is the only state that gesture is reachable in.
|
||||
State = ShellState.Unlocked,
|
||||
};
|
||||
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await shell.DisposeAsync();
|
||||
await workspace.DisposeAsync();
|
||||
caches.Dispose();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ClickingTheSearchPill_OpensTheQuickConnectPalette()
|
||||
{
|
||||
await LayoutHarness.OnTheUiThreadAsync(
|
||||
() =>
|
||||
{
|
||||
var bar = new TitleBar { DataContext = shell };
|
||||
var window = LayoutHarness.HostAtMinimumSize(
|
||||
bar, LayoutHarness.MinimumWidth, LayoutHarness.TitleBarHeight);
|
||||
|
||||
try
|
||||
{
|
||||
shell.IsSearching.ShouldBeFalse("nothing has been pressed yet");
|
||||
|
||||
var pill = bar.GetVisualDescendants()
|
||||
.OfType<Button>()
|
||||
.First(button => button.Classes.Contains("search"));
|
||||
|
||||
var centre = pill.TranslatePoint(
|
||||
new Point(pill.Bounds.Width / 2, pill.Bounds.Height / 2), window)
|
||||
?? throw new InvalidOperationException("the pill is not in this window's tree");
|
||||
|
||||
window.MouseDown(centre, MouseButton.Left);
|
||||
window.MouseUp(centre, MouseButton.Left);
|
||||
|
||||
shell.IsSearching.ShouldBeTrue(
|
||||
"the pill is the click-through path Ctrl+K also opens — see ToggleSearchCommand");
|
||||
}
|
||||
finally
|
||||
{
|
||||
window.Close();
|
||||
}
|
||||
},
|
||||
Token);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user