refactor: remove placeholder join step

This commit is contained in:
lda
2026-09-05 17:47:57 +07:00 Verified
parent 043bda6a34
commit cccdbc0a47
42 changed files with 88 additions and 309 deletions
+1 -1
View File
@@ -226,7 +226,7 @@ def test_draft_step_requires_exactly_one_kind_key() -> None:
assert isinstance(steps, dict)
echo = steps["echo"]
assert isinstance(echo, dict)
echo["join"] = {}
echo["end"] = {"outcome": "ok"}
with pytest.raises(ValidationError) as exc_info:
WorkflowDraft.model_validate(draft)
+5 -6
View File
@@ -675,7 +675,7 @@ async def test_update_capability_step_rejects_wrong_kind_and_invalid_input_atomi
register_echo=True,
)
draft = _echo_draft()
draft["steps"]["joined"] = {"join": ["echo"]}
draft["steps"]["joined"] = {"end": {}}
await draft_api.create_draft_workspace(workspace_id="echo", draft=draft)
before = await draft_api.get_draft_workspace(
workspace_id="echo",
@@ -3136,7 +3136,7 @@ async def test_set_step_output_bindings_rejects_non_capability_step_without_muta
await draft_api.patch_draft_workspace(
workspace_id="non-capability-output-step",
revision=1,
patch=[{"op": "replace", "path": "/steps/render", "value": {"join": {}}}],
patch=[{"op": "replace", "path": "/steps/render", "value": {"end": {}}}],
)
before = await draft_api.get_draft_workspace(
workspace_id="non-capability-output-step",
@@ -3246,7 +3246,7 @@ async def test_set_step_output_bindings_stale_revision_precedes_non_capability_s
await draft_api.patch_draft_workspace(
workspace_id="stale-output-non-capability",
revision=1,
patch=[{"op": "replace", "path": "/steps/render", "value": {"join": {}}}],
patch=[{"op": "replace", "path": "/steps/render", "value": {"end": {}}}],
)
before = await draft_api.get_draft_workspace(
workspace_id="stale-output-non-capability",
@@ -3504,7 +3504,7 @@ async def test_set_step_input_bindings_rejects_non_capability_step_without_mutat
register_echo=True,
)
draft = _structured_report_draft()
draft["steps"]["report"] = {"join": {}}
draft["steps"]["report"] = {"end": {}}
await draft_api.create_draft_workspace(workspace_id="non_capability", draft=draft)
api = WorkflowApi(authoring.context, drafts=True)
before = await draft_api.get_draft_workspace(
@@ -3956,7 +3956,6 @@ async def test_add_step_from_capability_rejects_existing_step_id(
"interrupt",
{"interrupt": {"kind": "review", "outcomes": ["submitted"]}},
),
("join", {"join": {}}),
("end", {"end": {"outcome": "ok"}}),
(
"when",
@@ -4067,7 +4066,7 @@ async def test_add_step_stale_revision_wins_over_content_preflight(
before = await draft_api.get_draft_workspace(
workspace_id="draft_ws", include_draft=True
)
step = TypeAdapter(DraftStep).validate_python({"join": {}})
step = TypeAdapter(DraftStep).validate_python({"end": {}})
result = await api.add_step(
workspace_id="draft_ws",
+5 -34
View File
@@ -824,7 +824,6 @@ def test_wf_draft_add_help_lists_typed_step_commands_and_removes_flat_command()
"capability",
"interrupt",
"foreach",
"join",
"end",
"when",
"choose",
@@ -1531,7 +1530,7 @@ def test_wf_draft_add_foreach_builds_concurrent_policy(monkeypatch) -> None:
assert calls[1]["step"].foreach.concurrent.max_outstanding == 20
def test_wf_draft_add_join_and_end_build_concrete_steps(monkeypatch) -> None:
def test_wf_draft_add_end_builds_concrete_step(monkeypatch) -> None:
calls: list[dict[str, Any]] = []
class FakeHandlers:
@@ -1544,25 +1543,6 @@ def test_wf_draft_add_join_and_end_build_concrete_steps(monkeypatch) -> None:
"wf_cli.commands.draft_add.load_cli_context", lambda _ctx: context
)
join_result = runner.invoke(
app,
[
"draft",
"add",
"join",
"workspace",
"--revision",
"1",
"--step",
"joined",
"--from-step",
"each_issue",
"--from-outcome",
"done",
"--route",
"done=finish",
],
)
end_result = runner.invoke(
app,
[
@@ -1571,7 +1551,7 @@ def test_wf_draft_add_join_and_end_build_concrete_steps(monkeypatch) -> None:
"end",
"workspace",
"--revision",
"2",
"1",
"--step",
"finish",
"--outcome",
@@ -1579,12 +1559,9 @@ def test_wf_draft_add_join_and_end_build_concrete_steps(monkeypatch) -> None:
],
)
assert join_result.exit_code == 0, join_result.output
assert end_result.exit_code == 0, end_result.output
assert calls[0]["step"].model_dump(mode="json") == {"join": {}}
assert calls[0]["routes"] == {"done": "finish"}
assert calls[1]["step"].model_dump(mode="json") == {"end": {"outcome": "completed"}}
assert calls[1]["routes"] is None
assert calls[0]["step"].model_dump(mode="json") == {"end": {"outcome": "completed"}}
assert calls[0]["routes"] is None
def test_wf_draft_add_control_commands_reject_invalid_input_before_api_call(
@@ -1788,12 +1765,9 @@ def test_wf_draft_add_control_commands_reject_invalid_input_before_api_call(
def test_wf_draft_add_control_command_help_is_type_specific() -> None:
interrupt = runner.invoke(app, ["draft", "add", "interrupt", "--help"])
foreach = runner.invoke(app, ["draft", "add", "foreach", "--help"])
join = runner.invoke(app, ["draft", "add", "join", "--help"])
end = runner.invoke(app, ["draft", "add", "end", "--help"])
assert (
interrupt.exit_code == foreach.exit_code == join.exit_code == end.exit_code == 0
)
assert interrupt.exit_code == foreach.exit_code == end.exit_code == 0
assert "--request-schema-file" in interrupt.output
assert "--resume-schema-file" in interrupt.output
assert "--request" in interrupt.output
@@ -1806,9 +1780,6 @@ def test_wf_draft_add_control_command_help_is_type_specific() -> None:
assert "--item-error" in foreach.output
assert "--collect-to" in foreach.output
assert "--request-schema-file" not in foreach.output
assert "--from-step" in join.output
assert "--route" in join.output
assert "--request-schema-file" not in join.output
assert "--outcome" in end.output
assert "--route" not in end.output
+8 -21
View File
@@ -771,14 +771,14 @@ def test_wf_remote_capability_free_draft_lifecycle(monkeypatch, tmp_path) -> Non
[
"draft",
"add",
"join",
"end",
"control_ws",
"--revision",
"1",
"--step",
"gate",
"--route",
"done=finish",
"finish",
"--outcome",
"error",
],
[
"draft",
@@ -787,26 +787,14 @@ def test_wf_remote_capability_free_draft_lifecycle(monkeypatch, tmp_path) -> Non
"--revision",
"2",
"--step",
"gate",
],
[
"draft",
"add",
"end",
"control_ws",
"--revision",
"3",
"--step",
"finish",
"--outcome",
"error",
],
[
"draft",
"set-contract",
"control_ws",
"--revision",
"4",
"3",
"--outcome",
"error",
],
@@ -824,10 +812,10 @@ def test_wf_remote_capability_free_draft_lifecycle(monkeypatch, tmp_path) -> Non
assert '"status": "valid"' in results[-1].output
assert inspected.exit_code == 0, inspected.output
payload = json.loads(inspected.output)
assert payload["revision"] == 5
assert payload["draft"]["start"] == "gate"
assert payload["revision"] == 4
assert payload["draft"]["start"] == "finish"
assert payload["draft"]["outcomes"] == ["error"]
assert set(payload["draft"]["steps"]) == {"gate", "finish"}
assert set(payload["draft"]["steps"]) == {"finish"}
def test_wf_draft_export_uses_remote_get_and_writes_only_draft(
@@ -2409,7 +2397,6 @@ def test_wf_draft_add_control_steps_use_generic_rpc_target(
"completed_with_errors": "__end__",
},
),
("join", ["--route", "done=__end__"], {}, {"done": "__end__"}),
("end", ["--outcome", "ok"], {"outcome": "ok"}, None),
(
"when",
-1
View File
@@ -67,7 +67,6 @@ def test_schema_compact_alias_is_json_outline_without_refs() -> None:
"SubgraphNode",
"ConditionNode",
"ForeachNode",
"JoinNode",
"EndNode",
"InterruptNode",
]
+1 -1
View File
@@ -92,7 +92,7 @@ def test_generates_the_complete_real_workflow_contract() -> None:
assert len(manifest["operations"]) == 72
assert len({operation["method"] for operation in manifest["operations"]}) == 72
assert len(schemas) == 142
assert len(schemas) == 141
assert len(manifest["components"]["errors"]) == 1
assert all(
set(operation["result"]["schema"]) == {"$ref"}
+2 -2
View File
@@ -2090,7 +2090,7 @@ def test_add_draft_step_params_reject_invalid_kind_and_route_source() -> None:
"workspace_id": "ws",
"revision": 1,
"step_id": "bad",
"step": {"use": "demo.echo", "join": {}},
"step": {"use": "demo.echo", "end": {}},
}
)
@@ -2104,7 +2104,7 @@ def test_add_draft_step_params_reject_invalid_kind_and_route_source() -> None:
"workspace_id": "ws",
"revision": 1,
"step_id": "new",
"step": {"join": {}},
"step": {"end": {}},
"incoming": incoming,
}
)
+13 -26
View File
@@ -13,7 +13,6 @@ from wf_api.surface import RouteSource, WorkflowDraftSurface
from wf_artifacts.drafts.models import (
DraftEndPayload,
DraftEndStep,
DraftJoinStep,
DraftStep,
)
from wf_core import END
@@ -573,32 +572,25 @@ async def test_rpc_client_builds_capability_free_draft_lifecycle(tmp_path) -> No
workspace_id="control_first",
name="control_first",
)
joined = await client.add_step(
workspace_id="control_first",
revision=created["revision"],
step_id="gate",
step=DraftJoinStep(join={}),
routes={"done": "finish"},
)
started = await client.set_draft_start(
workspace_id="control_first",
revision=joined["revision"],
step_id="gate",
)
ended = await client.add_step(
workspace_id="control_first",
revision=started["revision"],
revision=created["revision"],
step_id="finish",
step=DraftEndStep(end=DraftEndPayload(outcome="error")),
)
contracted = await client.set_draft_contract(
started = await client.set_draft_start(
workspace_id="control_first",
revision=ended["revision"],
step_id="finish",
)
contracted = await client.set_draft_contract(
workspace_id="control_first",
revision=started["revision"],
outcomes=("error",),
)
stale = await client.set_draft_start(
workspace_id="control_first",
revision=ended["revision"],
revision=started["revision"],
step_id="finish",
)
validated = await client.validate_draft_workspace(workspace_id="control_first")
@@ -609,22 +601,18 @@ async def test_rpc_client_builds_capability_free_draft_lifecycle(tmp_path) -> No
)
assert created["revision"] == 1
assert joined["revision"] == 2
assert ended["revision"] == 2
assert started["revision"] == 3
assert ended["revision"] == 4
assert contracted["revision"] == 5
assert contracted["revision"] == 4
assert stale["status"] == "conflict"
assert stale["diagnostics"][0]["code"] == "revision_conflict"
assert validated["status"] == "valid"
assert "compiled_plan" in compiled
assert compiled["compiled_plan"]["start"] == "gate"
assert compiled["compiled_plan"]["start"] == "finish"
draft = inspected.get("draft")
assert draft is not None
assert draft["start"] == "gate"
assert draft["steps"] == {
"gate": {"join": {}},
"finish": {"end": {"outcome": "error"}},
}
assert draft["start"] == "finish"
assert draft["steps"] == {"finish": {"end": {"outcome": "error"}}}
def test_rpc_client_satisfies_draft_surface_static_shape() -> None:
@@ -1226,7 +1214,6 @@ async def test_rpc_client_preserves_nested_local_path_strings() -> None:
"outcomes": ["submitted"],
},
),
("join", TypeAdapter(DraftStep).validate_python({"join": {}}), {}),
("end", TypeAdapter(DraftStep).validate_python({"end": {}}), {"outcome": "ok"}),
(
"when",