Merge branch 'worktree-agent-a349413889618d94c' into fix/flow-debugger-arch-review
This commit is contained in:
@@ -119,6 +119,73 @@ public class FlowDebuggerPageTests : BunitContext
|
||||
Assert.NotNull(cut.Find("[data-test='flow-graph-empty']"));
|
||||
Assert.Equal("Not run", cut.Find("[data-test='flow-state']").TextContent.Trim());
|
||||
Assert.True(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
|
||||
// arch-review F3: a Deployer gets the whole surface — entry point, both modes, Run.
|
||||
Assert.NotNull(cut.Find("button[data-test='flow-entry-method']"));
|
||||
Assert.NotNull(cut.Find("button[data-test='flow-mode-live']"));
|
||||
Assert.NotNull(cut.Find("button[data-test='flow-mode-replay']"));
|
||||
}
|
||||
|
||||
// ---- F3: Replay opens to the OperationalAudit roles; Live stays Deployer-only ----------------
|
||||
|
||||
[Fact]
|
||||
public void Renders_ForViewer_ReplayOnly_WithNoLiveControls()
|
||||
{
|
||||
// A Viewer holds OperationalAudit but not Deployer: the page opens (it is the
|
||||
// Audit Log / Execution Chain drill-in target) pinned to Replay, with no way to
|
||||
// start a Live run.
|
||||
RegisterServices(role: "Viewer");
|
||||
|
||||
var cut = Render<FlowDebuggerPage>();
|
||||
|
||||
Assert.NotNull(cut.Find("[data-test='flow-toolbar']"));
|
||||
Assert.NotNull(cut.Find("input[data-test='flow-execution-id']"));
|
||||
Assert.NotNull(cut.Find("button[data-test='flow-load']"));
|
||||
Assert.NotNull(cut.Find("[data-test='flow-replay-only']"));
|
||||
|
||||
Assert.Empty(cut.FindAll("button[data-test='flow-run']"));
|
||||
Assert.Empty(cut.FindAll("button[data-test='flow-mode-live']"));
|
||||
Assert.Empty(cut.FindAll("button[data-test='flow-entry-method']"));
|
||||
Assert.Empty(cut.FindAll("button[data-test='flow-entry-value-change']"));
|
||||
Assert.Empty(cut.FindAll("select[data-test='flow-method-select']"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Viewer_LoadsAReplay_ButGetsNoRetryOrDiscardOnAParkedNode()
|
||||
{
|
||||
// Retry / Discard relay a command to the site — a Deployer act. The auditor sees
|
||||
// the Parked node and its detail, but not the two action buttons.
|
||||
RegisterServices(role: "Viewer");
|
||||
var root = Guid.NewGuid();
|
||||
var (parked, _, _) = ParkedThenResolved(root);
|
||||
_flow.ReplayAsync(root, Arg.Any<CancellationToken>()).Returns(parked);
|
||||
var nav = Services.GetRequiredService<NavigationManager>();
|
||||
nav.NavigateTo($"/deployment/flow-debugger?executionId={root}");
|
||||
|
||||
var cut = Render<FlowDebuggerPage>();
|
||||
cut.Instance.Delay = (_, _) => Task.CompletedTask;
|
||||
|
||||
cut.WaitForAssertion(() => Assert.Equal("Completed", cut.Find("[data-test='flow-state']").TextContent.Trim()));
|
||||
cut.Find("g[data-test='flow-node'][data-kind='ApiCall']").Click();
|
||||
|
||||
Assert.Empty(cut.FindAll("button[data-test='flow-step-retry']"));
|
||||
Assert.Empty(cut.FindAll("button[data-test='flow-step-discard']"));
|
||||
_flow.Received(1).ReplayAsync(root, Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Viewer_DrillInWithAMethodId_DoesNotOpenTheLiveRunSurface()
|
||||
{
|
||||
// ?methodId= is a Live-run drill-in. For a non-Deployer it must not put the page
|
||||
// into Live mode or surface the Run button.
|
||||
RegisterServices(role: "Viewer");
|
||||
var nav = Services.GetRequiredService<NavigationManager>();
|
||||
nav.NavigateTo("/deployment/flow-debugger?methodId=4");
|
||||
|
||||
var cut = Render<FlowDebuggerPage>();
|
||||
|
||||
Assert.Empty(cut.FindAll("button[data-test='flow-run']"));
|
||||
Assert.Empty(cut.FindAll("select[data-test='flow-method-select']"));
|
||||
Assert.NotNull(cut.Find("input[data-test='flow-execution-id']"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user