mirror of
https://github.com/langgenius/dify.git
synced 2026-03-08 08:57:37 +08:00
119 lines
4.0 KiB
Python
119 lines
4.0 KiB
Python
from unittest.mock import MagicMock
|
|
|
|
import services.app_generate_service as app_generate_service_module
|
|
from models.model import AppMode
|
|
from services.app_generate_service import AppGenerateService
|
|
|
|
|
|
class _DummyRateLimit:
|
|
def __init__(self, client_id: str, max_active_requests: int) -> None:
|
|
self.client_id = client_id
|
|
self.max_active_requests = max_active_requests
|
|
|
|
@staticmethod
|
|
def gen_request_key() -> str:
|
|
return "dummy-request-id"
|
|
|
|
def enter(self, request_id: str | None = None) -> str:
|
|
return request_id or "dummy-request-id"
|
|
|
|
def exit(self, request_id: str) -> None:
|
|
return None
|
|
|
|
def generate(self, generator, request_id: str):
|
|
return generator
|
|
|
|
|
|
def test_workflow_blocking_injects_pause_state_config(mocker, monkeypatch):
|
|
monkeypatch.setattr(app_generate_service_module.dify_config, "BILLING_ENABLED", False)
|
|
mocker.patch("services.app_generate_service.RateLimit", _DummyRateLimit)
|
|
|
|
workflow = MagicMock()
|
|
workflow.id = "workflow-id"
|
|
workflow.created_by = "owner-id"
|
|
|
|
mocker.patch.object(AppGenerateService, "_get_workflow", return_value=workflow)
|
|
|
|
generator_spy = mocker.patch(
|
|
"services.app_generate_service.WorkflowAppGenerator.generate",
|
|
return_value={"result": "ok"},
|
|
)
|
|
|
|
app_model = MagicMock()
|
|
app_model.mode = AppMode.WORKFLOW
|
|
app_model.id = "app-id"
|
|
app_model.tenant_id = "tenant-id"
|
|
app_model.max_active_requests = 0
|
|
app_model.is_agent = False
|
|
|
|
user = MagicMock()
|
|
user.id = "user-id"
|
|
|
|
result = AppGenerateService.generate(
|
|
app_model=app_model,
|
|
user=user,
|
|
args={"inputs": {"k": "v"}},
|
|
invoke_from=MagicMock(),
|
|
streaming=False,
|
|
)
|
|
|
|
assert result == {"result": "ok"}
|
|
|
|
call_kwargs = generator_spy.call_args.kwargs
|
|
pause_state_config = call_kwargs.get("pause_state_config")
|
|
assert pause_state_config is not None
|
|
assert pause_state_config.state_owner_user_id == "owner-id"
|
|
|
|
|
|
def test_advanced_chat_blocking_returns_dict_and_does_not_use_event_retrieval(mocker, monkeypatch):
|
|
"""
|
|
Regression test: ADVANCED_CHAT in blocking mode should return a plain dict
|
|
(non-streaming), and must not go through the async retrieve_events path.
|
|
Keeps behavior consistent with WORKFLOW blocking branch.
|
|
"""
|
|
# Disable billing and stub RateLimit to a no-op that just passes values through
|
|
monkeypatch.setattr(app_generate_service_module.dify_config, "BILLING_ENABLED", False)
|
|
mocker.patch("services.app_generate_service.RateLimit", _DummyRateLimit)
|
|
|
|
# Arrange a fake workflow and wire AppGenerateService._get_workflow to return it
|
|
workflow = MagicMock()
|
|
workflow.id = "workflow-id"
|
|
mocker.patch.object(AppGenerateService, "_get_workflow", return_value=workflow)
|
|
|
|
# Spy on the streaming retrieval path to ensure it's NOT called
|
|
retrieve_spy = mocker.patch("services.app_generate_service.AdvancedChatAppGenerator.retrieve_events")
|
|
|
|
# Make AdvancedChatAppGenerator.generate return a plain dict when streaming=False
|
|
generate_spy = mocker.patch(
|
|
"services.app_generate_service.AdvancedChatAppGenerator.generate",
|
|
return_value={"result": "ok"},
|
|
)
|
|
|
|
# Minimal app model for ADVANCED_CHAT
|
|
app_model = MagicMock()
|
|
app_model.mode = AppMode.ADVANCED_CHAT
|
|
app_model.id = "app-id"
|
|
app_model.tenant_id = "tenant-id"
|
|
app_model.max_active_requests = 0
|
|
app_model.is_agent = False
|
|
|
|
user = MagicMock()
|
|
user.id = "user-id"
|
|
|
|
# Must include query and inputs for AdvancedChatAppGenerator
|
|
args = {"workflow_id": "wf-1", "query": "hello", "inputs": {}}
|
|
|
|
# Act: call service with streaming=False (blocking mode)
|
|
result = AppGenerateService.generate(
|
|
app_model=app_model,
|
|
user=user,
|
|
args=args,
|
|
invoke_from=MagicMock(),
|
|
streaming=False,
|
|
)
|
|
|
|
# Assert: returns the dict from generate(), and did not call retrieve_events()
|
|
assert result == {"result": "ok"}
|
|
assert generate_spy.call_args.kwargs.get("streaming") is False
|
|
retrieve_spy.assert_not_called()
|