Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions BusLane.Tests/Views/AlertsDialogTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace BusLane.Tests.Views;

using FluentAssertions;

public class AlertsDialogTests
{
[Fact]
public void AlertsDialog_UsesSharedDialogScaffold()
{
// Arrange
var xaml = File.ReadAllText(GetDialogPath());

// Assert
xaml.Should().Contain("Classes=\"dialog-header\"");
xaml.Should().Contain("Classes=\"dialog-body\"");
xaml.Should().Contain("Classes=\"dialog-footer\"");
}

private static string GetDialogPath()
{
return Path.GetFullPath(Path.Combine(
AppContext.BaseDirectory,
"..",
"..",
"..",
"..",
"BusLane",
"Views",
"Dialogs",
"AlertsDialog.axaml"));
}
}
67 changes: 67 additions & 0 deletions BusLane.Tests/Views/AppThemeResourceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
namespace BusLane.Tests.Views;

using FluentAssertions;

public class AppThemeResourceTests
{
[Fact]
public void AppResources_DefineSharedDashboardSurfaceTokens()
{
// Arrange
var xaml = File.ReadAllText(GetAppPath());

// Assert
xaml.Should().Contain("x:Key=\"LayerBackground\"");
xaml.Should().Contain("x:Key=\"DashboardTileBackground\"");
xaml.Should().Contain("x:Key=\"AccentBrandSubtle\"");
}

[Fact]
public void AppStyles_DefineSharedToggleAndMenuStyles()
{
// Arrange
var xaml = File.ReadAllText(GetStylesPath());

// Assert
xaml.Should().Contain("<Style Selector=\"ToggleSwitch\">");
xaml.Should().Contain("<Style Selector=\"CheckBox\">");
xaml.Should().Contain("<Style Selector=\"ContextMenu\">");
xaml.Should().Contain("<Style Selector=\"MenuItem\">");
}

[Fact]
public void AppStyles_PanelToggleUsesMinimumAccessibleHitTarget()
{
// Arrange
var xaml = File.ReadAllText(GetStylesPath());

// Assert
xaml.Should().Contain("<Setter Property=\"MinWidth\" Value=\"36\"/>");
xaml.Should().Contain("<Setter Property=\"MinHeight\" Value=\"36\"/>");
}

private static string GetAppPath()
{
return Path.GetFullPath(Path.Combine(
AppContext.BaseDirectory,
"..",
"..",
"..",
"..",
"BusLane",
"App.axaml"));
}

private static string GetStylesPath()
{
return Path.GetFullPath(Path.Combine(
AppContext.BaseDirectory,
"..",
"..",
"..",
"..",
"BusLane",
"Styles",
"AppStyles.axaml"));
}
}
43 changes: 43 additions & 0 deletions BusLane.Tests/Views/CodeEditorStyleTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace BusLane.Tests.Views;

using System.Linq;
using System.Xml.Linq;
using FluentAssertions;

public class CodeEditorStyleTests
Expand Down Expand Up @@ -55,6 +57,25 @@ public void AppStyles_CodeEditorTemplateOverrides_DoNotTargetAllBorders()
xaml.Should().NotContain("<Style Selector=\"TextBox.code-editor:pointerover /template/ Border\">");
}

[Fact]
public void SendMessageDialog_CodeEditorRemainsInsideSharedDialogBody()
{
// Arrange
var xaml = File.ReadAllText(GetSendMessageDialogPath());
var document = XDocument.Parse(xaml);
var codeEditor = document
.Descendants()
.FirstOrDefault(element => HasClass(element, "code-editor"));

// Assert
codeEditor.Should().NotBeNull("SendMessageDialog should include a code editor");
codeEditor!
.Ancestors()
.Any(element => HasClass(element, "dialog-body"))
.Should()
.BeTrue("the code editor should be nested inside the shared dialog body");
}

private static string GetAppStylesPath()
{
return Path.GetFullPath(Path.Combine(
Expand All @@ -68,6 +89,20 @@ private static string GetAppStylesPath()
"AppStyles.axaml"));
}

private static string GetSendMessageDialogPath()
{
return Path.GetFullPath(Path.Combine(
AppContext.BaseDirectory,
"..",
"..",
"..",
"..",
"BusLane",
"Views",
"Dialogs",
"SendMessageDialog.axaml"));
}

private static string GetStyleBlock(string xaml, string selector)
{
var styleTag = $"<Style Selector=\"{selector}\">";
Expand All @@ -79,4 +114,12 @@ private static string GetStyleBlock(string xaml, string selector)

return xaml[startIndex..(endIndex + "</Style>".Length)];
}

private static bool HasClass(XElement element, string className)
{
var classes = element.Attribute("Classes")?.Value;
return classes?
.Split(' ', StringSplitOptions.RemoveEmptyEntries)
.Contains(className, StringComparer.Ordinal) == true;
}
}
99 changes: 99 additions & 0 deletions BusLane.Tests/Views/ConnectionLibraryDialogTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
namespace BusLane.Tests.Views;

using FluentAssertions;

public class ConnectionLibraryDialogTests
{
[Fact]
public void ConnectionLibraryDialog_UsesSharedDialogRegions()
{
// Arrange
var xaml = File.ReadAllText(GetDialogPath());

// Assert
xaml.Should().Contain("Classes=\"dialog-header\"");
xaml.Should().Contain("Classes=\"dialog-body\"");
}

[Fact]
public void ConnectionLibraryDialog_SeparatesQuickActionsFromFormSurface()
{
// Arrange
var xaml = File.ReadAllText(GetDialogPath());

// Assert
xaml.Should().Contain("Classes=\"connection-library-command-bar\"");
xaml.Should().NotContain("Background=\"{DynamicResource SurfaceSubtle}\"");
}

[Fact]
public void ConnectionLibraryDialog_LeftAlignsBackupPassphraseSection()
{
// Arrange
var xaml = File.ReadAllText(GetDialogPath());
var passphraseIndex = xaml.IndexOf("Text=\"Backup passphrase\"", StringComparison.Ordinal);

// Assert
passphraseIndex.Should().BeGreaterThanOrEqualTo(0);

// Act
var blockStart = xaml.LastIndexOf("<StackPanel", passphraseIndex, StringComparison.Ordinal);
blockStart.Should().BeGreaterThanOrEqualTo(0);

var passphraseSection = xaml[blockStart..passphraseIndex];
passphraseSection.Should().Contain("HorizontalAlignment=\"Left\"");
}

[Fact]
public void ConnectionLibraryDialog_PlacesBackupActionsInlineWithPassphraseField()
{
// Arrange
var xaml = File.ReadAllText(GetDialogPath());

// Act
var passphraseIndex = xaml.IndexOf("Text=\"Backup passphrase\"", StringComparison.Ordinal);
var exportIndex = xaml.IndexOf("Text=\"Export Backup\"", StringComparison.Ordinal);
var importIndex = xaml.IndexOf("Text=\"Import Backup\"", StringComparison.Ordinal);

// Assert
passphraseIndex.Should().BeGreaterThanOrEqualTo(0);
exportIndex.Should().BeGreaterThan(passphraseIndex);
importIndex.Should().BeGreaterThan(passphraseIndex);
xaml.Should().Contain("ColumnDefinitions=\"*,Auto,Auto\"");
}

[Fact]
public void ConnectionLibraryDialog_UsesWiderBackupPassphraseLayout()
{
// Arrange
var xaml = File.ReadAllText(GetDialogPath());

// Assert
xaml.Should().Contain("MaxWidth=\"520\"");
}

[Fact]
public void ConnectionLibraryDialog_UsesFixedDialogSize()
{
// Arrange
var xaml = File.ReadAllText(GetDialogPath());

// Assert
xaml.Should().Contain("Width=\"900\"");
xaml.Should().Contain("Height=\"720\"");
}

private static string GetDialogPath()
{
return Path.GetFullPath(Path.Combine(
AppContext.BaseDirectory,
"..",
"..",
"..",
"..",
"BusLane",
"Views",
"Dialogs",
"ConnectionLibraryDialog.axaml"));
}
}
75 changes: 75 additions & 0 deletions BusLane.Tests/Views/DialogScaffoldTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
namespace BusLane.Tests.Views;

using FluentAssertions;

public class DialogScaffoldTests
{
[Fact]
public void AppStyles_DefineDialogHeaderBodyFooterStyles()
{
// Arrange
var xaml = File.ReadAllText(GetStylesPath());

// Assert
xaml.Should().Contain("Border.dialog-header");
xaml.Should().Contain("Border.dialog-body");
xaml.Should().Contain("Border.dialog-footer");
}

[Fact]
public void SettingsDialog_UsesSharedDialogRegions()
{
// Arrange
var xaml = File.ReadAllText(GetSettingsDialogPath());

// Assert
xaml.Should().Contain("Classes=\"dialog-header\"");
xaml.Should().Contain("Classes=\"dialog-body\"");
xaml.Should().Contain("Classes=\"dialog-footer\"");
}

[Fact]
public void SettingsDialog_UsesSharedSettingsRowForRefreshInterval()
{
// Arrange
var xaml = File.ReadAllText(GetSettingsDialogPath());
var refreshIntervalIndex = xaml.IndexOf("Text=\"Refresh interval\"", StringComparison.Ordinal);

// Assert
refreshIntervalIndex.Should().BeGreaterThanOrEqualTo(0);

// Act
var rowStart = xaml.LastIndexOf("<Grid", refreshIntervalIndex, StringComparison.Ordinal);
rowStart.Should().BeGreaterThanOrEqualTo(0);

var refreshIntervalRow = xaml[rowStart..refreshIntervalIndex];
refreshIntervalRow.Should().Contain("Classes=\"settings-row\"");
}

private static string GetStylesPath()
{
return Path.GetFullPath(Path.Combine(
AppContext.BaseDirectory,
"..",
"..",
"..",
"..",
"BusLane",
"Styles",
"AppStyles.axaml"));
}

private static string GetSettingsDialogPath()
{
return Path.GetFullPath(Path.Combine(
AppContext.BaseDirectory,
"..",
"..",
"..",
"..",
"BusLane",
"Views",
"Dialogs",
"SettingsDialog.axaml"));
}
}
Loading
Loading