170 lines
5.1 KiB
Python
170 lines
5.1 KiB
Python
import json
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
import pytest
|
|
|
|
from services.image_generation_service import ImageGenerationService
|
|
|
|
|
|
def test_comfyui_prompt_injection_uses_node_index_for_nested_nodes(tmp_path):
|
|
service = ImageGenerationService(str(tmp_path))
|
|
workflow = {
|
|
"group": {
|
|
"nodes": {
|
|
1: {
|
|
"class_type": "Reroute",
|
|
"_meta": {"title": "Input Prompt"},
|
|
"inputs": {"prompt": [2, 0]},
|
|
},
|
|
2: {
|
|
"class_type": "PrimitiveNode",
|
|
"inputs": {"value": "old prompt"},
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
service._inject_prompt_into_workflow(workflow, "new prompt")
|
|
|
|
assert workflow["group"]["nodes"][2]["inputs"]["value"] == "new prompt"
|
|
|
|
|
|
def test_comfyui_seed_randomization_updates_common_seed_inputs(tmp_path):
|
|
service = ImageGenerationService(str(tmp_path))
|
|
workflow = {
|
|
"1": {
|
|
"class_type": "KSampler",
|
|
"inputs": {
|
|
"seed": 111,
|
|
"steps": 20,
|
|
"cfg": 8.0,
|
|
"sampler_name": "euler",
|
|
},
|
|
},
|
|
"2": {
|
|
"class_type": "RandomNoise",
|
|
"inputs": {
|
|
"noise_seed": 222,
|
|
"width": 1024,
|
|
"height": 1024,
|
|
},
|
|
},
|
|
"3": {
|
|
"class_type": "KSamplerAdvanced",
|
|
"inputs": {
|
|
"noise_seed": "333",
|
|
"start_at_step": 0,
|
|
"end_at_step": 20,
|
|
},
|
|
},
|
|
"4": {
|
|
"class_type": "CustomSamplerWithVariations",
|
|
"inputs": {
|
|
"main_seed": 444,
|
|
"variation_seed": 555,
|
|
"seed_offset": 2,
|
|
},
|
|
},
|
|
}
|
|
|
|
with patch.object(
|
|
service,
|
|
"_generate_comfyui_seed",
|
|
side_effect=[1001, 1002, 1003, 1004, 1005],
|
|
):
|
|
assert service._inject_random_seeds_into_workflow(workflow) == 5
|
|
|
|
assert workflow["1"]["inputs"]["seed"] == 1001
|
|
assert workflow["2"]["inputs"]["noise_seed"] == 1002
|
|
assert workflow["3"]["inputs"]["noise_seed"] == "1003"
|
|
assert workflow["4"]["inputs"]["main_seed"] == 1004
|
|
assert workflow["4"]["inputs"]["variation_seed"] == 1005
|
|
|
|
assert workflow["1"]["inputs"]["steps"] == 20
|
|
assert workflow["1"]["inputs"]["cfg"] == 8.0
|
|
assert workflow["2"]["inputs"]["width"] == 1024
|
|
assert workflow["4"]["inputs"]["seed_offset"] == 2
|
|
|
|
|
|
def test_comfyui_seed_randomization_updates_linked_seed_source(tmp_path):
|
|
service = ImageGenerationService(str(tmp_path))
|
|
workflow = {
|
|
"1": {
|
|
"class_type": "KSampler",
|
|
"inputs": {
|
|
"seed": ["99", 0],
|
|
"steps": 20,
|
|
},
|
|
},
|
|
"99": {
|
|
"class_type": "PrimitiveNode",
|
|
"inputs": {
|
|
"value": 123,
|
|
},
|
|
},
|
|
"100": {
|
|
"class_type": "RandomInt",
|
|
"inputs": {
|
|
"min": 0,
|
|
"max": 999,
|
|
},
|
|
},
|
|
}
|
|
|
|
with patch.object(service, "_generate_comfyui_seed", return_value=987654):
|
|
assert service._inject_random_seeds_into_workflow(workflow) == 1
|
|
|
|
assert workflow["1"]["inputs"]["seed"] == ["99", 0]
|
|
assert workflow["99"]["inputs"]["value"] == 987654
|
|
assert workflow["100"]["inputs"] == {"min": 0, "max": 999}
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_generate_image_comfyui_randomizes_seed_before_submit(tmp_path):
|
|
workflow = {
|
|
"1": {
|
|
"class_type": "CLIPTextEncode",
|
|
"_meta": {"title": "Input Prompt"},
|
|
"inputs": {"text": "old prompt"},
|
|
},
|
|
"2": {
|
|
"class_type": "KSampler",
|
|
"inputs": {"seed": 123, "steps": 20},
|
|
},
|
|
}
|
|
service = ImageGenerationService(str(tmp_path))
|
|
submitted_workflow = {}
|
|
|
|
async def fake_submit(_session, _comfyui_url, workflow_arg):
|
|
submitted_workflow.update(workflow_arg)
|
|
return "prompt-id"
|
|
|
|
with patch(
|
|
"services.image_generation_service.get_comfyui_url_env",
|
|
return_value="http://comfy.example",
|
|
), patch(
|
|
"services.image_generation_service.get_comfyui_workflow_env",
|
|
return_value=json.dumps(workflow),
|
|
), patch.object(
|
|
service, "_generate_comfyui_seed", return_value=42
|
|
), patch.object(
|
|
service,
|
|
"_submit_comfyui_workflow",
|
|
new=AsyncMock(side_effect=fake_submit),
|
|
), patch.object(
|
|
service,
|
|
"_wait_for_comfyui_completion",
|
|
new=AsyncMock(return_value={"prompt-id": {"outputs": {}}}),
|
|
), patch.object(
|
|
service,
|
|
"_download_comfyui_image",
|
|
new=AsyncMock(return_value=str(tmp_path / "image.png")),
|
|
):
|
|
image_path = await service.generate_image_comfyui(
|
|
"new prompt", str(tmp_path)
|
|
)
|
|
|
|
assert image_path == str(tmp_path / "image.png")
|
|
assert submitted_workflow["1"]["inputs"]["text"] == "new prompt"
|
|
assert submitted_workflow["2"]["inputs"]["seed"] == 42
|