test: use SQLite sessions in services workflow (#39116)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Asuka Minato 2026-07-21 12:40:02 +09:00 committed by GitHub
parent 97e6a14c13
commit d333aa31ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,9 +1,11 @@
"""Tests for human-input delivery with a persisted draft workflow."""
import json
import uuid
from types import SimpleNamespace
from unittest.mock import MagicMock
import pytest
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import Session, sessionmaker
from core.workflow.human_input_adapter import (
EmailDeliveryConfig,
@ -14,12 +16,42 @@ from core.workflow.human_input_adapter import (
)
from core.workflow.nodes.human_input.entities import HumanInputNodeData
from graphon.enums import BuiltinNodeTypes
from models import Account
from models.enums import AppStatus
from models.model import App, AppMode
from models.workflow import Workflow, WorkflowType
from services import workflow_service as workflow_service_module
from services.workflow_service import WorkflowService
TENANT_ID = "11111111-1111-1111-1111-111111111111"
APP_ID = "22222222-2222-2222-2222-222222222222"
ACCOUNT_ID = "33333333-3333-3333-3333-333333333333"
def _make_service() -> WorkflowService:
return WorkflowService(session_maker=sessionmaker())
def _make_service(sqlite_session: Session) -> WorkflowService:
return WorkflowService(
session_maker=sessionmaker(bind=sqlite_session.get_bind(), expire_on_commit=False),
)
def _app() -> App:
return App(
id=APP_ID,
tenant_id=TENANT_ID,
name="Test App",
description="",
mode=AppMode.WORKFLOW,
status=AppStatus.NORMAL,
enable_site=False,
enable_api=False,
max_active_requests=None,
)
def _account() -> Account:
account = Account(name="Test User", email="test@example.com")
account.id = ACCOUNT_ID
return account
def _build_node_config(delivery_methods: list[EmailDeliveryMethod]) -> dict[str, object]:
@ -36,6 +68,37 @@ def _build_node_config(delivery_methods: list[EmailDeliveryMethod]) -> dict[str,
}
def _persist_workflow(sqlite_session: Session, delivery_methods: list[EmailDeliveryMethod]) -> None:
node_config = _build_node_config(delivery_methods)
node_data = node_config["data"]
assert isinstance(node_data, HumanInputNodeData)
workflow = Workflow.new(
tenant_id=TENANT_ID,
app_id=APP_ID,
type=WorkflowType.WORKFLOW,
version=Workflow.VERSION_DRAFT,
graph=json.dumps(
{
"nodes": [
{
"id": node_config["id"],
"data": node_data.model_dump(mode="json"),
}
],
"edges": [],
}
),
features="{}",
created_by=ACCOUNT_ID,
environment_variables=[],
conversation_variables=[],
rag_pipeline_variables=[],
)
sqlite_session.add(workflow)
sqlite_session.commit()
sqlite_session.expunge_all()
def _make_email_method(enabled: bool = True, debug_mode: bool = False) -> EmailDeliveryMethod:
return EmailDeliveryMethod(
id=uuid.uuid4(),
@ -52,11 +115,11 @@ def _make_email_method(enabled: bool = True, debug_mode: bool = False) -> EmailD
)
def test_human_input_delivery_requires_draft_workflow():
service = _make_service()
service.get_draft_workflow = MagicMock(return_value=None) # type: ignore[method-assign]
app_model = SimpleNamespace(tenant_id="tenant-1", id="app-1")
account = SimpleNamespace(id="account-1")
@pytest.mark.parametrize("sqlite_session", [(Workflow,)], indirect=True)
def test_human_input_delivery_requires_draft_workflow(sqlite_session: Session):
service = _make_service(sqlite_session)
app_model = _app()
account = _account()
with pytest.raises(ValueError, match="Workflow not initialized"):
service.test_human_input_delivery(
@ -64,17 +127,19 @@ def test_human_input_delivery_requires_draft_workflow():
account=account,
node_id="node-1",
delivery_method_id="delivery-1",
session=MagicMock(),
session=sqlite_session,
)
assert sqlite_session.in_transaction()
def test_human_input_delivery_allows_disabled_method(monkeypatch: pytest.MonkeyPatch):
service = _make_service()
@pytest.mark.parametrize("sqlite_session", [(Workflow,)], indirect=True)
def test_human_input_delivery_allows_disabled_method(
monkeypatch: pytest.MonkeyPatch,
sqlite_session: Session,
):
service = _make_service(sqlite_session)
delivery_method = _make_email_method(enabled=False)
node_config = _build_node_config([delivery_method])
workflow = MagicMock()
workflow.get_node_config_by_id.return_value = node_config
service.get_draft_workflow = MagicMock(return_value=workflow) # type: ignore[method-assign]
_persist_workflow(sqlite_session, [delivery_method])
service._build_human_input_variable_pool = MagicMock(return_value=MagicMock()) # type: ignore[attr-defined]
node_stub = MagicMock()
node_stub.render_form_content_before_submission.return_value = "rendered"
@ -91,27 +156,29 @@ def test_human_input_delivery_allows_disabled_method(monkeypatch: pytest.MonkeyP
MagicMock(return_value=test_service_instance),
)
app_model = SimpleNamespace(tenant_id="tenant-1", id="app-1")
account = SimpleNamespace(id="account-1")
app_model = _app()
account = _account()
service.test_human_input_delivery(
app_model=app_model,
account=account,
node_id="node-1",
delivery_method_id=str(delivery_method.id),
session=MagicMock(),
session=sqlite_session,
)
test_service_instance.send_test.assert_called_once()
assert sqlite_session.in_transaction()
def test_human_input_delivery_dispatches_to_test_service(monkeypatch: pytest.MonkeyPatch):
service = _make_service()
@pytest.mark.parametrize("sqlite_session", [(Workflow,)], indirect=True)
def test_human_input_delivery_dispatches_to_test_service(
monkeypatch: pytest.MonkeyPatch,
sqlite_session: Session,
):
service = _make_service(sqlite_session)
delivery_method = _make_email_method(enabled=True)
node_config = _build_node_config([delivery_method])
workflow = MagicMock()
workflow.get_node_config_by_id.return_value = node_config
service.get_draft_workflow = MagicMock(return_value=workflow) # type: ignore[method-assign]
_persist_workflow(sqlite_session, [delivery_method])
service._build_human_input_variable_pool = MagicMock(return_value=MagicMock()) # type: ignore[attr-defined]
node_stub = MagicMock()
node_stub.render_form_content_before_submission.return_value = "rendered"
@ -128,8 +195,8 @@ def test_human_input_delivery_dispatches_to_test_service(monkeypatch: pytest.Mon
MagicMock(return_value=test_service_instance),
)
app_model = SimpleNamespace(tenant_id="tenant-1", id="app-1")
account = SimpleNamespace(id="account-1")
app_model = _app()
account = _account()
service.test_human_input_delivery(
app_model=app_model,
@ -137,21 +204,23 @@ def test_human_input_delivery_dispatches_to_test_service(monkeypatch: pytest.Mon
node_id="node-1",
delivery_method_id=str(delivery_method.id),
inputs={"#node-1.output#": "value"},
session=MagicMock(),
session=sqlite_session,
)
pool_args = service._build_human_input_variable_pool.call_args.kwargs
assert pool_args["manual_inputs"] == {"#node-1.output#": "value"}
test_service_instance.send_test.assert_called_once()
assert sqlite_session.in_transaction()
def test_human_input_delivery_debug_mode_overrides_recipients(monkeypatch: pytest.MonkeyPatch):
service = _make_service()
@pytest.mark.parametrize("sqlite_session", [(Workflow,)], indirect=True)
def test_human_input_delivery_debug_mode_overrides_recipients(
monkeypatch: pytest.MonkeyPatch,
sqlite_session: Session,
):
service = _make_service(sqlite_session)
delivery_method = _make_email_method(enabled=True, debug_mode=True)
node_config = _build_node_config([delivery_method])
workflow = MagicMock()
workflow.get_node_config_by_id.return_value = node_config
service.get_draft_workflow = MagicMock(return_value=workflow) # type: ignore[method-assign]
_persist_workflow(sqlite_session, [delivery_method])
service._build_human_input_variable_pool = MagicMock(return_value=MagicMock()) # type: ignore[attr-defined]
node_stub = MagicMock()
node_stub.render_form_content_before_submission.return_value = "rendered"
@ -168,15 +237,15 @@ def test_human_input_delivery_debug_mode_overrides_recipients(monkeypatch: pytes
MagicMock(return_value=test_service_instance),
)
app_model = SimpleNamespace(tenant_id="tenant-1", id="app-1")
account = SimpleNamespace(id="account-1")
app_model = _app()
account = _account()
service.test_human_input_delivery(
app_model=app_model,
account=account,
node_id="node-1",
delivery_method_id=str(delivery_method.id),
session=MagicMock(),
session=sqlite_session,
)
test_service_instance.send_test.assert_called_once()
@ -188,3 +257,4 @@ def test_human_input_delivery_debug_mode_overrides_recipients(monkeypatch: pytes
recipient = sent_method.config.recipients.items[0]
assert isinstance(recipient, MemberRecipient)
assert recipient.reference_id == account.id
assert sqlite_session.in_transaction()