feat(secrets-ui): add/rotate/delete modal + audited gated reveal
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
using Bunit;
|
||||
using Bunit.TestDoubles;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ZB.MOM.WW.Audit;
|
||||
using ZB.MOM.WW.Secrets.Abstractions;
|
||||
using ZB.MOM.WW.Secrets.Ui.Components;
|
||||
using ZB.MOM.WW.Secrets.Ui.Tests.Fakes;
|
||||
|
||||
namespace ZB.MOM.WW.Secrets.Ui.Tests;
|
||||
|
||||
public class ConfirmDeleteModalTests : TestContext
|
||||
{
|
||||
[Fact]
|
||||
public void ConfirmDeleteModal_IsInPageModal_NoJsDialog()
|
||||
{
|
||||
// Strict JS interop mode: any IJSRuntime call (a JS confirm/alert dialog) would throw,
|
||||
// proving the confirmation is a rendered in-page modal, not a browser dialog.
|
||||
JSInterop.Mode = JSRuntimeMode.Strict;
|
||||
|
||||
var store = new RecordingSecretStore();
|
||||
var audit = new CapturingAuditWriter();
|
||||
Services.AddSingleton<ISecretStore>(store);
|
||||
Services.AddSingleton<IAuditWriter>(audit);
|
||||
|
||||
var name = new SecretName("db/primary");
|
||||
var auth = this.AddTestAuthorization();
|
||||
auth.SetAuthorized("carol");
|
||||
auth.SetPolicies(SecretsAuthorization.ManagePolicy);
|
||||
|
||||
bool deleted = false;
|
||||
var cut = RenderComponent<ConfirmDeleteModal>(p => p
|
||||
.Add(c => c.Visible, true)
|
||||
.Add(c => c.Name, name)
|
||||
.Add(c => c.OnDeleted, () => deleted = true));
|
||||
|
||||
// The confirmation is a rendered in-page modal element.
|
||||
Assert.NotEmpty(cut.FindAll(".modal"));
|
||||
Assert.Contains("db/primary", cut.Markup);
|
||||
|
||||
cut.Find("[data-testid=confirm-delete]").Click();
|
||||
|
||||
// Confirm tombstoned the row (with the resolved actor) and wrote a secret.delete audit.
|
||||
Assert.Single(store.Deletes);
|
||||
Assert.Equal("db/primary", store.Deletes[0].Name.Value);
|
||||
Assert.Equal("carol", store.Deletes[0].Actor);
|
||||
Assert.True(deleted);
|
||||
|
||||
Assert.Single(audit.Events);
|
||||
AuditEvent evt = audit.Events[0];
|
||||
Assert.Equal("secret.delete", evt.Action);
|
||||
Assert.Equal(AuditOutcome.Success, evt.Outcome);
|
||||
Assert.Equal("Secrets", evt.Category);
|
||||
Assert.Equal("db/primary", evt.Target);
|
||||
Assert.Equal("carol", evt.Actor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConfirmDeleteModal_Cancel_DoesNotDelete()
|
||||
{
|
||||
var store = new RecordingSecretStore();
|
||||
var audit = new CapturingAuditWriter();
|
||||
Services.AddSingleton<ISecretStore>(store);
|
||||
Services.AddSingleton<IAuditWriter>(audit);
|
||||
|
||||
var name = new SecretName("db/primary");
|
||||
var auth = this.AddTestAuthorization();
|
||||
auth.SetAuthorized("carol");
|
||||
auth.SetPolicies(SecretsAuthorization.ManagePolicy);
|
||||
|
||||
bool cancelled = false;
|
||||
var cut = RenderComponent<ConfirmDeleteModal>(p => p
|
||||
.Add(c => c.Visible, true)
|
||||
.Add(c => c.Name, name)
|
||||
.Add(c => c.OnCancelled, () => cancelled = true));
|
||||
|
||||
cut.Find("[data-testid=cancel-delete]").Click();
|
||||
|
||||
Assert.True(cancelled);
|
||||
Assert.Empty(store.Deletes);
|
||||
Assert.Empty(audit.Events);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConfirmDeleteModal_NotVisible_RendersNothing()
|
||||
{
|
||||
var store = new RecordingSecretStore();
|
||||
var audit = new CapturingAuditWriter();
|
||||
Services.AddSingleton<ISecretStore>(store);
|
||||
Services.AddSingleton<IAuditWriter>(audit);
|
||||
|
||||
var name = new SecretName("db/primary");
|
||||
this.AddTestAuthorization().SetAuthorized("carol");
|
||||
|
||||
var cut = RenderComponent<ConfirmDeleteModal>(p => p
|
||||
.Add(c => c.Visible, false)
|
||||
.Add(c => c.Name, name));
|
||||
|
||||
Assert.Empty(cut.FindAll(".modal"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user