Duplicate flows and dashboards: POST /flows/{name}/duplicate and /dashboards/{name}/duplicate copy the working copy into {name}_copy (then _copy_2, ...) as an unpublished draft with " (copy)" on the title. A flow copy takes its node sources as drafts and leaves origin and runtime.json behind; copying code nodes is a superuser's (the save check, now taking the replaced copy). Client regenerated

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-16 09:21:30 +02:00
co-authored by Claude Opus 5.5
parent 8b1a456cd3
commit 8a868e0f26
9 changed files with 215 additions and 9 deletions
+20 -1
View File
@@ -7,7 +7,7 @@ import pytest
from fluksio.flow.controller import FlowController
from fluksio.flow.messages import MessageSpec
from fluksio.flow.schemas import FlowDef, NodeDef
from fluksio.flow.schemas import FlowDef, FlowOrigin, NodeDef
from fluksio.flow.store import FlowStore, StaleVersion
SOURCE = "def process():\n return {}\n"
@@ -181,3 +181,22 @@ def test_renaming_carries_the_draft_and_repoints_other_drafts(store: FlowStore):
assert store.read_flow("display", draft=True).nodes[0].requires[0].name == (
"warmth.temp"
)
def test_a_duplicate_is_a_local_draft_of_what_the_editor_shows(store: FlowStore):
store.write_flow(a_flow(title="Warm").model_copy(update={"origin": FlowOrigin()}))
store.write_node_source("heating", "sensor", SOURCE)
store.write_node_source("heating", "sensor", EDITED, draft=True)
store.write_enabled("heating", False)
copy = store.duplicate_flow("heating")
assert (copy.name, copy.title, copy.version) == ("heating_copy", "Warm (copy)", 1)
assert copy.origin is None
assert store.has_draft("heating_copy") and not store.is_published("heating_copy")
assert store.read_node_source("heating_copy", "sensor", draft=True) == EDITED
assert not (store.root / "heating_copy" / "runtime.json").exists()
assert store.duplicate_flow("heating").name == "heating_copy_2"
store.publish_flow("heating_copy", copy.version)
assert store.read_node_source("heating_copy", "sensor") == EDITED