first commit
This commit is contained in:
@@ -0,0 +1,320 @@
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Bunit;
|
||||
using SufiChain.SufiBlazor.Components.Overlays;
|
||||
using SufiChain.SufiBlazor.Localization;
|
||||
using Xunit;
|
||||
|
||||
namespace SufiChain.SufiBlazor.Tests.Components.Overlays;
|
||||
|
||||
file class StubStringLocalizer : IStringLocalizer<SufiBlazorResource>
|
||||
{
|
||||
public LocalizedString this[string name] => new(name, name);
|
||||
public LocalizedString this[string name, params object[] arguments] => new(name, string.Format(CultureInfo.InvariantCulture, name, arguments));
|
||||
public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures) => Array.Empty<LocalizedString>();
|
||||
}
|
||||
|
||||
public class SbConfirmDialogTests : BunitContext
|
||||
{
|
||||
public SbConfirmDialogTests()
|
||||
{
|
||||
Services.AddSingleton<IStringLocalizer<SufiBlazorResource>>(new StubStringLocalizer());
|
||||
}
|
||||
|
||||
private IRenderedComponent<SbConfirmDialog> RenderConfirmDialog(
|
||||
Action<ComponentParameterCollectionBuilder<SbConfirmDialog>>? configure = null)
|
||||
{
|
||||
return Render<SbConfirmDialog>(p => configure?.Invoke(p));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DoesNotRenderWhenClosed()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Confirm")
|
||||
.Add(x => x.Message, "Are you sure?"));
|
||||
|
||||
// Assert
|
||||
Assert.Empty(cut.FindAll(".sb-confirm-dialog-overlay"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RendersWhenShowCalled()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Confirm")
|
||||
.Add(x => x.Message, "Proceed?"));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert
|
||||
var overlay = cut.Find(".sb-confirm-dialog-overlay");
|
||||
Assert.NotNull(overlay);
|
||||
var dialog = cut.Find(".sb-confirm-dialog");
|
||||
Assert.NotNull(dialog);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RendersTitleAndMessage()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Delete Item")
|
||||
.Add(x => x.Message, "This cannot be undone."));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert
|
||||
Assert.Contains("Delete Item", cut.Markup);
|
||||
Assert.Contains("This cannot be undone.", cut.Markup);
|
||||
var title = cut.Find(".sb-confirm-dialog__title");
|
||||
Assert.NotNull(title);
|
||||
var message = cut.Find(".sb-confirm-dialog__message");
|
||||
Assert.NotNull(message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RendersChildContent()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Confirm")
|
||||
.AddChildContent(b => b.AddMarkupContent(0, "<p>Custom content</p>")));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert
|
||||
Assert.Contains("Custom content", cut.Markup);
|
||||
var body = cut.Find(".sb-confirm-dialog__body");
|
||||
Assert.NotNull(body);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DoesNotRenderMessageWhenNull()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Title only"));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert
|
||||
Assert.Empty(cut.FindAll(".sb-confirm-dialog__message"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AppliesVariantClass()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Confirm")
|
||||
.Add(x => x.Variant, SbConfirmDialogVariant.Danger));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert
|
||||
var dialog = cut.Find(".sb-confirm-dialog");
|
||||
Assert.Contains("sb-confirm-dialog--danger", dialog.ClassList);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(SbConfirmDialogVariant.Default, "default")]
|
||||
[InlineData(SbConfirmDialogVariant.Danger, "danger")]
|
||||
[InlineData(SbConfirmDialogVariant.Warning, "warning")]
|
||||
[InlineData(SbConfirmDialogVariant.Info, "info")]
|
||||
public async Task AppliesCorrectVariantClass(SbConfirmDialogVariant variant, string expectedClass)
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Confirm")
|
||||
.Add(x => x.Variant, variant));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert
|
||||
var dialog = cut.Find(".sb-confirm-dialog");
|
||||
Assert.Contains($"sb-confirm-dialog--{expectedClass}", dialog.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ShowsCancelButtonByDefault()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p.Add(x => x.Title, "Confirm"));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert - two buttons: Cancel and Confirm
|
||||
var buttons = cut.FindAll("button");
|
||||
Assert.True(buttons.Count >= 2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HidesCancelButtonWhenShowCancelButtonFalse()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Confirm")
|
||||
.Add(x => x.ShowCancelButton, false));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert - only Confirm button (SbButton with Ghost variant is Cancel)
|
||||
var ghostButtons = cut.FindAll("button.sb-button--ghost");
|
||||
Assert.Empty(ghostButtons);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AppliesCustomButtonText()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Confirm")
|
||||
.Add(x => x.ConfirmText, "Yes, delete")
|
||||
.Add(x => x.CancelText, "Keep"));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert
|
||||
Assert.Contains("Yes, delete", cut.Markup);
|
||||
Assert.Contains("Keep", cut.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AppliesClassParameter()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Confirm")
|
||||
.Add(x => x.Class, "my-dialog"));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert
|
||||
var dialog = cut.Find(".sb-confirm-dialog");
|
||||
Assert.Contains("my-dialog", dialog.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HasAlertDialogRole()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p.Add(x => x.Title, "Confirm"));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert
|
||||
var dialog = cut.Find(".sb-confirm-dialog");
|
||||
Assert.Equal("alertdialog", dialog.GetAttribute("role"));
|
||||
Assert.Equal("true", dialog.GetAttribute("aria-modal"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ConfirmButtonInvokesOnConfirm()
|
||||
{
|
||||
// Arrange
|
||||
var confirmed = false;
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Confirm")
|
||||
.Add(x => x.OnConfirm, EventCallback.Factory.Create(this, () => confirmed = true)));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Act - click Confirm (Solid button, not Ghost)
|
||||
var confirmBtn = cut.FindAll("button.sb-button--solid").Last();
|
||||
await cut.InvokeAsync(() => confirmBtn.Click());
|
||||
|
||||
// Assert
|
||||
Assert.True(confirmed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CancelButtonInvokesOnCancel()
|
||||
{
|
||||
// Arrange
|
||||
var cancelled = false;
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Confirm")
|
||||
.Add(x => x.OnCancel, EventCallback.Factory.Create(this, () => cancelled = true)));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Act - click Cancel (Ghost button)
|
||||
var cancelBtn = cut.Find("button.sb-button--ghost");
|
||||
await cut.InvokeAsync(() => cancelBtn!.Click());
|
||||
|
||||
// Assert
|
||||
Assert.True(cancelled);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ShowAsyncReturnsTrueWhenConfirmed()
|
||||
{
|
||||
// Arrange
|
||||
var cut = RenderConfirmDialog(p => p
|
||||
.Add(x => x.Title, "Confirm")
|
||||
.Add(x => x.ShowCancelButton, false));
|
||||
Task<bool> showTask = null!;
|
||||
await cut.InvokeAsync(() => { showTask = cut.Instance.ShowAsync(); });
|
||||
cut.Render();
|
||||
|
||||
// Act
|
||||
var confirmBtn = cut.Find("button.sb-button--solid");
|
||||
await cut.InvokeAsync(() => confirmBtn!.Click());
|
||||
|
||||
// Assert
|
||||
var result = await showTask;
|
||||
Assert.True(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ShowAsyncReturnsFalseWhenCancelled()
|
||||
{
|
||||
// Arrange
|
||||
var cut = RenderConfirmDialog(p => p.Add(x => x.Title, "Confirm"));
|
||||
Task<bool> showTask = null!;
|
||||
await cut.InvokeAsync(() => { showTask = cut.Instance.ShowAsync(); });
|
||||
cut.Render();
|
||||
|
||||
// Act - click Cancel
|
||||
var cancelBtn = cut.Find("button.sb-button--ghost");
|
||||
await cut.InvokeAsync(() => cancelBtn!.Click());
|
||||
|
||||
// Assert
|
||||
var result = await showTask;
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CloseHidesDialog()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p.Add(x => x.Title, "Confirm"));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
Assert.NotNull(cut.Find(".sb-confirm-dialog-overlay"));
|
||||
|
||||
await cut.InvokeAsync(() => cut.Instance.Close());
|
||||
cut.Render();
|
||||
|
||||
// Assert
|
||||
Assert.Empty(cut.FindAll(".sb-confirm-dialog-overlay"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RendersIconSection()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderConfirmDialog(p => p.Add(x => x.Title, "Confirm"));
|
||||
await cut.InvokeAsync(() => cut.Instance.Show());
|
||||
cut.Render();
|
||||
|
||||
// Assert
|
||||
var icon = cut.Find(".sb-confirm-dialog__icon");
|
||||
Assert.NotNull(icon);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user