fix(central-ui): Flow Debugger — remount ParameterValueForm per script so stale form state cannot block Run
Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
This commit is contained in:
@@ -691,4 +691,64 @@ public class FlowDebuggerPageTests : BunitContext
|
||||
cut.WaitForAssertion(() => Assert.Equal("Manual", cut.Find("select[data-test='flow-script-select']").GetAttribute("value")));
|
||||
_ = _flow.Received().PredictScriptAsync(7, "Manual", Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Two call-kind scripts declaring BYTE-IDENTICAL parameter definitions — the case that makes
|
||||
/// <c>ParameterValueForm</c> skip its reparse (and its <c>ValidChanged</c>) and keeps the previous
|
||||
/// script's raw text and parse errors. The page must remount the form per script instead.
|
||||
/// </summary>
|
||||
private static readonly FlowScriptOption Manual2 = new("Manual2", "Call", null,
|
||||
"""{"type":"object","properties":{"n":{"type":"integer"}},"required":["n"]}""", 20);
|
||||
|
||||
private void WireInstanceWithTwinScripts()
|
||||
{
|
||||
_templates.GetInstancesBySiteIdAsync(1, Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<Instance>>([new Instance("Sim01") { Id = 7, SiteId = 1, TemplateId = 10 }]));
|
||||
_flow.GetInstanceScriptsAsync(7, Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyList<FlowScriptOption>>([Manual, Manual2, Tick]));
|
||||
_flow.PredictScriptAsync(7, Arg.Any<string>(), Arg.Any<CancellationToken>()).Returns(ThreeNodePrediction());
|
||||
}
|
||||
|
||||
private IRenderedComponent<FlowDebuggerPage> ChooseScriptWithAnInvalidParameter()
|
||||
{
|
||||
var cut = Render<FlowDebuggerPage>();
|
||||
cut.Find("button[data-test='flow-entry-script']").Click();
|
||||
cut.Find("select[data-test='flow-site-select']").Change("1");
|
||||
cut.Find("select[data-test='flow-instance-select']").Change("7");
|
||||
cut.Find("select[data-test='flow-script-select']").Change("Manual");
|
||||
cut.Find("#param-n").Input("abc"); // not an integer: the form parks a parse error
|
||||
Assert.True(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
|
||||
return cut;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ScriptEntry_SwitchingBetweenCallKindScripts_ResetsTheFormAndValidity()
|
||||
{
|
||||
RegisterServices();
|
||||
WireInstanceWithTwinScripts();
|
||||
var cut = ChooseScriptWithAnInvalidParameter();
|
||||
|
||||
cut.Find("select[data-test='flow-script-select']").Change("Manual2");
|
||||
|
||||
// A fresh form: no echo of the previous script's text, and no stale parse error keeping
|
||||
// Run disabled invisibly — Run is disabled only because the required field is unset.
|
||||
Assert.Equal(string.Empty, cut.Find("#param-n").GetAttribute("value"));
|
||||
Assert.True(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
|
||||
|
||||
cut.Find("#param-n").Input("5");
|
||||
Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ScriptEntry_SwitchingFromAnInvalidFormToANoParameterScript_EnablesRun()
|
||||
{
|
||||
RegisterServices();
|
||||
WireInstanceWithTwinScripts();
|
||||
var cut = ChooseScriptWithAnInvalidParameter();
|
||||
|
||||
cut.Find("select[data-test='flow-script-select']").Change("Tick");
|
||||
|
||||
Assert.Contains("takes no parameters", cut.Find("[data-test='flow-inputs']").TextContent);
|
||||
Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user