chore: snapshot workflow migration progress
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from app.core.process_steps import StepName
|
||||
from app.domains.rendering.workflow_schema import WorkflowConfig
|
||||
|
||||
|
||||
@@ -72,6 +73,35 @@ def test_workflow_schema_rejects_unknown_node_params():
|
||||
)
|
||||
|
||||
|
||||
def test_workflow_schema_rejects_unregistered_nodes_from_registry(monkeypatch):
|
||||
from app.domains.rendering import workflow_schema as schema_module
|
||||
|
||||
original = schema_module.get_node_definition
|
||||
|
||||
def fake_get_node_definition(step):
|
||||
if step == StepName.GLB_BBOX:
|
||||
return None
|
||||
return original(step)
|
||||
|
||||
monkeypatch.setattr(schema_module, "get_node_definition", fake_get_node_definition)
|
||||
|
||||
with pytest.raises(ValidationError, match="is not registered in workflow_node_registry"):
|
||||
WorkflowConfig.model_validate(
|
||||
{
|
||||
"version": 1,
|
||||
"nodes": [
|
||||
{
|
||||
"id": "bbox",
|
||||
"step": StepName.GLB_BBOX.value,
|
||||
"params": {},
|
||||
},
|
||||
],
|
||||
"edges": [],
|
||||
"ui": {"family": "order_line"},
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_workflow_schema_accepts_known_node_params():
|
||||
config = WorkflowConfig.model_validate(
|
||||
{
|
||||
@@ -92,6 +122,149 @@ def test_workflow_schema_accepts_known_node_params():
|
||||
assert config.ui.family == "order_line"
|
||||
|
||||
|
||||
def test_workflow_schema_rejects_invalid_glb_path_format():
|
||||
with pytest.raises(ValidationError, match="must point to a .glb file"):
|
||||
WorkflowConfig.model_validate(
|
||||
{
|
||||
"version": 1,
|
||||
"nodes": [
|
||||
{
|
||||
"id": "bbox",
|
||||
"step": "glb_bbox",
|
||||
"params": {"glb_path": "/tmp/model.gltf"},
|
||||
},
|
||||
],
|
||||
"edges": [],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_workflow_schema_rejects_invalid_template_id_override_format():
|
||||
with pytest.raises(ValidationError, match="must be a valid UUID"):
|
||||
WorkflowConfig.model_validate(
|
||||
{
|
||||
"version": 1,
|
||||
"nodes": [
|
||||
{
|
||||
"id": "template",
|
||||
"step": "resolve_template",
|
||||
"params": {"template_id_override": "not-a-uuid"},
|
||||
},
|
||||
],
|
||||
"edges": [],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_workflow_schema_rejects_invalid_material_library_path_format():
|
||||
with pytest.raises(ValidationError, match="must point to a .blend file"):
|
||||
WorkflowConfig.model_validate(
|
||||
{
|
||||
"version": 1,
|
||||
"nodes": [
|
||||
{
|
||||
"id": "template",
|
||||
"step": "resolve_template",
|
||||
"params": {"material_library_path": "/tmp/library.txt"},
|
||||
},
|
||||
],
|
||||
"edges": [],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_workflow_schema_rejects_invalid_noise_threshold_format():
|
||||
with pytest.raises(ValidationError, match="must be a valid numeric string"):
|
||||
WorkflowConfig.model_validate(
|
||||
{
|
||||
"version": 1,
|
||||
"nodes": [
|
||||
{
|
||||
"id": "render",
|
||||
"step": "blender_still",
|
||||
"params": {"noise_threshold": "fast"},
|
||||
},
|
||||
],
|
||||
"edges": [],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_workflow_schema_rejects_invalid_bg_color_format():
|
||||
with pytest.raises(ValidationError, match="must be a hex color"):
|
||||
WorkflowConfig.model_validate(
|
||||
{
|
||||
"version": 1,
|
||||
"nodes": [
|
||||
{
|
||||
"id": "turntable",
|
||||
"step": "blender_turntable",
|
||||
"params": {"bg_color": "blue"},
|
||||
},
|
||||
],
|
||||
"edges": [],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_workflow_schema_rejects_invalid_output_name_suffix_format():
|
||||
with pytest.raises(ValidationError, match="may only contain letters, numbers"):
|
||||
WorkflowConfig.model_validate(
|
||||
{
|
||||
"version": 1,
|
||||
"nodes": [
|
||||
{
|
||||
"id": "blend",
|
||||
"step": "export_blend",
|
||||
"params": {"output_name_suffix": "../unsafe"},
|
||||
},
|
||||
],
|
||||
"edges": [],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_workflow_schema_accepts_empty_optional_text_overrides():
|
||||
config = WorkflowConfig.model_validate(
|
||||
{
|
||||
"version": 1,
|
||||
"nodes": [
|
||||
{
|
||||
"id": "template",
|
||||
"step": "resolve_template",
|
||||
"params": {
|
||||
"template_id_override": "",
|
||||
"material_library_path": "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"id": "render",
|
||||
"step": "blender_still",
|
||||
"params": {
|
||||
"noise_threshold": "",
|
||||
"material_override": "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"id": "turntable",
|
||||
"step": "blender_turntable",
|
||||
"params": {"bg_color": ""},
|
||||
},
|
||||
{
|
||||
"id": "blend",
|
||||
"step": "export_blend",
|
||||
"params": {"output_name_suffix": ""},
|
||||
},
|
||||
],
|
||||
"edges": [],
|
||||
"ui": {"family": "order_line"},
|
||||
}
|
||||
)
|
||||
|
||||
assert config.ui is not None
|
||||
assert config.ui.family == "order_line"
|
||||
|
||||
|
||||
def test_workflow_schema_rejects_ui_family_mismatch():
|
||||
with pytest.raises(ValidationError, match="ui.family"):
|
||||
WorkflowConfig.model_validate(
|
||||
@@ -226,6 +399,32 @@ def test_workflow_schema_accepts_transitive_contract_wiring():
|
||||
assert config.ui.execution_mode == "graph"
|
||||
|
||||
|
||||
def test_workflow_schema_accepts_cad_intake_contract_wiring_with_shared_bbox_node():
|
||||
config = WorkflowConfig.model_validate(
|
||||
{
|
||||
"version": 1,
|
||||
"nodes": [
|
||||
{"id": "resolve_step", "step": "resolve_step_path", "params": {}},
|
||||
{"id": "export_glb", "step": "occ_glb_export", "params": {}},
|
||||
{"id": "bbox", "step": "glb_bbox", "params": {}},
|
||||
{"id": "threejs_thumb", "step": "threejs_render", "params": {}},
|
||||
{"id": "save", "step": "thumbnail_save", "params": {}},
|
||||
],
|
||||
"edges": [
|
||||
{"from": "resolve_step", "to": "export_glb"},
|
||||
{"from": "export_glb", "to": "bbox"},
|
||||
{"from": "export_glb", "to": "threejs_thumb"},
|
||||
{"from": "bbox", "to": "threejs_thumb"},
|
||||
{"from": "threejs_thumb", "to": "save"},
|
||||
],
|
||||
"ui": {"family": "cad_file", "execution_mode": "graph"},
|
||||
}
|
||||
)
|
||||
|
||||
assert config.ui is not None
|
||||
assert config.ui.family == "cad_file"
|
||||
|
||||
|
||||
def test_workflow_schema_rejects_mixed_family_graph_execution():
|
||||
with pytest.raises(ValidationError, match="single-family"):
|
||||
WorkflowConfig.model_validate(
|
||||
|
||||
Reference in New Issue
Block a user