refactor(api): rename form definitions fields

This commit is contained in:
QuantumGhost 2026-04-26 10:51:49 +08:00
parent 7a12d46a45
commit 74f17d0ec8
17 changed files with 147 additions and 127 deletions

View File

@ -5,7 +5,7 @@ from typing import Any, TypeAlias
from pydantic import BaseModel, ConfigDict, Field
from graphon.nodes.human_input.entities import FormInput, UserAction
from graphon.nodes.human_input.entities import FormInputConfig, UserActionConfig
from models.execution_extra_content import ExecutionContentType
@ -16,8 +16,8 @@ class HumanInputFormDefinition(BaseModel):
node_id: str
node_title: str
form_content: str
inputs: Sequence[FormInput] = Field(default_factory=list)
actions: Sequence[UserAction] = Field(default_factory=list)
inputs: Sequence[FormInputConfig] = Field(default_factory=list)
actions: Sequence[UserActionConfig] = Field(default_factory=list)
display_in_ui: bool = False
form_token: str | None = None
resolved_default_values: Mapping[str, Any] = Field(default_factory=dict)

View File

@ -17,7 +17,7 @@ from core.workflow.human_input_adapter import (
MemberRecipient,
WebAppDeliveryMethod,
)
from graphon.nodes.human_input.entities import FormDefinition, HumanInputNodeData, UserAction
from graphon.nodes.human_input.entities import FormDefinition, HumanInputNodeData, UserActionConfig
from models.account import (
Account,
AccountStatus,
@ -69,7 +69,7 @@ def _build_form_params(delivery_methods: list[DeliveryChannelConfig]) -> FormCre
title="Human Approval",
delivery_methods=delivery_methods,
form_content="<p>Approve?</p>",
user_actions=[UserAction(id="approve", title="Approve")],
user_actions=[UserActionConfig(id="approve", title="Approve")],
)
return FormCreateParams(
workflow_execution_id=str(uuid4()),
@ -185,7 +185,7 @@ class TestHumanInputFormRepositoryImplWithContainers:
title="Human Approval",
form_content="<p>Approve?</p>",
inputs=[],
user_actions=[UserAction(id="approve", title="Approve")],
user_actions=[UserActionConfig(id="approve", title="Approve")],
),
rendered_content="<p>Approve?</p>",
delivery_methods=[],
@ -220,7 +220,7 @@ class TestHumanInputFormRepositoryImplWithContainers:
title="Human Approval",
form_content="<p>Approve?</p>",
inputs=[],
user_actions=[UserAction(id="approve", title="Approve")],
user_actions=[UserActionConfig(id="approve", title="Approve")],
delivery_methods=[WebAppDeliveryMethod()],
),
rendered_content="<p>Approve?</p>",

View File

@ -21,7 +21,7 @@ from graphon.graph_engine import GraphEngine
from graphon.graph_engine.command_channels import InMemoryChannel
from graphon.nodes.end.end_node import EndNode
from graphon.nodes.end.entities import EndNodeData
from graphon.nodes.human_input.entities import HumanInputNodeData, UserAction
from graphon.nodes.human_input.entities import HumanInputNodeData, UserActionConfig
from graphon.nodes.human_input.enums import HumanInputFormStatus
from graphon.nodes.human_input.human_input_node import HumanInputNode
from graphon.nodes.start.entities import StartNodeData
@ -112,7 +112,7 @@ def _build_graph(
form_content="Awaiting human input",
inputs=[],
user_actions=[
UserAction(id="continue", title="Continue"),
UserActionConfig(id="continue", title="Continue"),
],
)
human_node = HumanInputNode(

View File

@ -15,8 +15,8 @@ from extensions.ext_storage import storage
from graphon.entities import WorkflowExecution
from graphon.entities.pause_reason import HumanInputRequired, PauseReasonType
from graphon.enums import WorkflowExecutionStatus
from graphon.nodes.human_input.entities import FormDefinition, FormInput, UserAction
from graphon.nodes.human_input.enums import FormInputType, HumanInputFormStatus
from graphon.nodes.human_input.entities import FormDefinition, ParagraphInputConfig, UserActionConfig
from graphon.nodes.human_input.enums import HumanInputFormStatus
from libs.datetime_utils import naive_utc_now
from models.enums import CreatorUserRole, WorkflowRunTriggeredFrom
from models.human_input import (
@ -638,8 +638,8 @@ class TestBuildHumanInputRequiredReason:
expiration_time = naive_utc_now()
form_definition = FormDefinition(
form_content="content",
inputs=[FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="name")],
user_actions=[UserAction(id="approve", title="Approve")],
inputs=[ParagraphInputConfig(output_variable_name="name")],
user_actions=[UserActionConfig(id="approve", title="Approve")],
rendered_content="rendered",
expiration_time=expiration_time,
default_values={"name": "Alice"},

View File

@ -177,9 +177,9 @@ def _create_submitted_form(
) -> HumanInputForm:
expiration_time = naive_utc_now() + timedelta(days=1)
form_definition = FormDefinition(
form_content="content",
inputs=[],
user_actions=[UserAction(id=action_id, title=action_title)],
form_content=form_content,
inputs=inputs or [],
user_actions=[UserActionConfig(id=action_id, title=action_title)],
rendered_content="rendered",
expiration_time=expiration_time,
node_title=node_title,

View File

@ -12,8 +12,7 @@ from controllers.console.app import workflow_run as workflow_run_module
from controllers.web.error import NotFoundError
from graphon.entities.pause_reason import HumanInputRequired
from graphon.enums import WorkflowExecutionStatus
from graphon.nodes.human_input.entities import FormInput, UserAction
from graphon.nodes.human_input.enums import FormInputType
from graphon.nodes.human_input.entities import ParagraphInputConfig, UserActionConfig
from libs import login as login_lib
from models.account import Account, AccountStatus, TenantAccountRole
from models.workflow import WorkflowRun
@ -63,8 +62,8 @@ def test_pause_details_returns_backstage_input_url(app: Flask, monkeypatch: pyte
reason = HumanInputRequired(
form_id="form-1",
form_content="content",
inputs=[FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="name")],
actions=[UserAction(id="approve", title="Approve")],
inputs=[ParagraphInputConfig(output_variable_name="name")],
actions=[UserActionConfig(id="approve", title="Approve")],
node_id="node-1",
node_title="Ask Name",
)

View File

@ -14,8 +14,7 @@ from core.workflow.system_variables import build_system_variables
from graphon.entities import WorkflowStartReason
from graphon.entities.pause_reason import HumanInputRequired
from graphon.graph_events import GraphRunPausedEvent
from graphon.nodes.human_input.entities import FormInput, UserAction
from graphon.nodes.human_input.enums import FormInputType
from graphon.nodes.human_input.entities import ParagraphInputConfig, UserActionConfig
from models.account import Account
from models.human_input import RecipientType
@ -156,10 +155,8 @@ def test_queue_workflow_paused_event_to_stream_responses(monkeypatch: pytest.Mon
reason = HumanInputRequired(
form_id="form-1",
form_content="Rendered",
inputs=[
FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="field", default=None),
],
actions=[UserAction(id="approve", title="Approve")],
inputs=[ParagraphInputConfig(output_variable_name="field")],
actions=[UserActionConfig(id="approve", title="Approve")],
node_id="node-id",
node_title="Human Step",
)

View File

@ -4,8 +4,7 @@ from core.entities.execution_extra_content import (
HumanInputFormDefinition,
HumanInputFormSubmissionData,
)
from graphon.nodes.human_input.entities import FormInput, UserAction
from graphon.nodes.human_input.enums import FormInputType
from graphon.nodes.human_input.entities import ParagraphInputConfig, UserActionConfig
from models.execution_extra_content import ExecutionContentType
@ -16,8 +15,8 @@ def test_human_input_content_defaults_and_domain_alias() -> None:
node_id="node-1",
node_title="Human Input",
form_content="Please confirm",
inputs=[FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="answer")],
actions=[UserAction(id="confirm", title="Confirm")],
inputs=[ParagraphInputConfig(output_variable_name="answer")],
actions=[UserActionConfig(id="confirm", title="Confirm")],
resolved_default_values={"answer": "yes"},
expiration_time=1_700_000_000,
)

View File

@ -23,7 +23,7 @@ from core.workflow.human_input_adapter import (
)
from graphon.nodes.human_input.entities import (
FormDefinition,
UserAction,
UserActionConfig,
)
from graphon.nodes.human_input.enums import HumanInputFormKind, HumanInputFormStatus
from libs.datetime_utils import naive_utc_now
@ -272,7 +272,7 @@ def _make_form_definition() -> str:
return FormDefinition(
form_content="hello",
inputs=[],
user_actions=[UserAction(id="submit", title="Submit")],
user_actions=[UserActionConfig(id="submit", title="Submit")],
rendered_content="<p>hello</p>",
expiration_time=naive_utc_now(),
).model_dump_json()

View File

@ -29,7 +29,7 @@ from core.workflow.human_input_adapter import (
MemberRecipient,
WebAppDeliveryMethod,
)
from graphon.nodes.human_input.entities import HumanInputNodeData, UserAction
from graphon.nodes.human_input.entities import HumanInputNodeData, UserActionConfig
from graphon.nodes.human_input.enums import HumanInputFormKind, HumanInputFormStatus
from libs.datetime_utils import naive_utc_now
from models.human_input import HumanInputFormRecipient, RecipientType

View File

@ -24,7 +24,14 @@ from graphon.graph_events import (
from graphon.nodes.base.entities import OutputVariableEntity
from graphon.nodes.end.end_node import EndNode
from graphon.nodes.end.entities import EndNodeData
from graphon.nodes.human_input.entities import HumanInputNodeData, UserAction
from graphon.nodes.human_input.entities import (
FileInputConfig,
FileListInputConfig,
HumanInputNodeData,
SelectInputConfig,
StringListSource,
UserActionConfig,
)
from graphon.nodes.human_input.enums import HumanInputFormStatus
from graphon.nodes.human_input.human_input_node import HumanInputNode
from graphon.nodes.start.entities import StartNodeData

View File

@ -36,20 +36,25 @@ from graphon.entities import GraphInitParams
from graphon.node_events import PauseRequestedEvent
from graphon.node_events.node import StreamCompletedEvent
from graphon.nodes.human_input.entities import (
FormInput,
FormInputDefault,
FileInputConfig,
FileListInputConfig,
HumanInputNodeData,
UserAction,
ParagraphInputConfig,
SelectInputConfig,
StringListSource,
StringSource,
UserActionConfig,
)
from graphon.nodes.human_input.enums import (
ButtonStyle,
FormInputType,
HumanInputFormStatus,
PlaceholderType,
TimeoutUnit,
ValueSourceType,
)
from graphon.nodes.human_input.human_input_node import HumanInputNode
from graphon.runtime import GraphRuntimeState, VariablePool
from graphon.variables.segments import ArrayFileSegment, FileSegment
from libs.datetime_utils import naive_utc_now
@ -195,27 +200,27 @@ class TestFormInput:
def test_text_input_with_constant_default(self):
"""Test text input with constant default value."""
default = FormInputDefault(type=PlaceholderType.CONSTANT, value="Enter your response here...")
default = StringSource(type=ValueSourceType.CONSTANT, value="Enter your response here...")
form_input = FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="user_input", default=default)
form_input = ParagraphInputConfig(output_variable_name="user_input", default=default)
assert form_input.type == FormInputType.TEXT_INPUT
assert form_input.type == FormInputType.PARAGRAPH
assert form_input.output_variable_name == "user_input"
assert form_input.default.type == PlaceholderType.CONSTANT
assert form_input.default.type == ValueSourceType.CONSTANT
assert form_input.default.value == "Enter your response here..."
def test_text_input_with_variable_default(self):
"""Test text input with variable default value."""
default = FormInputDefault(type=PlaceholderType.VARIABLE, selector=["node_123", "output_var"])
default = StringSource(type=ValueSourceType.VARIABLE, selector=["node_123", "output_var"])
form_input = FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="user_input", default=default)
form_input = ParagraphInputConfig(output_variable_name="user_input", default=default)
assert form_input.default.type == PlaceholderType.VARIABLE
assert form_input.default.type == ValueSourceType.VARIABLE
assert form_input.default.selector == ["node_123", "output_var"]
def test_form_input_without_default(self):
"""Test form input without default value."""
form_input = FormInput(type=FormInputType.PARAGRAPH, output_variable_name="description")
form_input = ParagraphInputConfig(output_variable_name="description")
assert form_input.type == FormInputType.PARAGRAPH
assert form_input.output_variable_name == "description"
@ -227,7 +232,7 @@ class TestUserAction:
def test_user_action_creation(self):
"""Test user action creation."""
action = UserAction(id="approve", title="Approve", button_style=ButtonStyle.PRIMARY)
action = UserActionConfig(id="approve", title="Approve", button_style=ButtonStyle.PRIMARY)
assert action.id == "approve"
assert action.title == "Approve"
@ -235,13 +240,13 @@ class TestUserAction:
def test_user_action_default_button_style(self):
"""Test user action with default button style."""
action = UserAction(id="cancel", title="Cancel")
action = UserActionConfig(id="cancel", title="Cancel")
assert action.button_style == ButtonStyle.DEFAULT
def test_user_action_length_boundaries(self):
"""Test user action id and title length boundaries."""
action = UserAction(id="a" * 20, title="b" * 20)
action = UserActionConfig(id="a" * 20, title="b" * 20)
assert action.id == "a" * 20
assert action.title == "b" * 20
@ -259,7 +264,7 @@ class TestUserAction:
data[field_name] = value
with pytest.raises(ValidationError) as exc_info:
UserAction.model_validate(data)
UserActionConfig.model_validate(data)
errors = exc_info.value.errors()
assert any(error["loc"] == (field_name,) and error["type"] == "string_too_long" for error in errors)
@ -273,14 +278,13 @@ class TestHumanInputNodeData:
delivery_methods = [WebAppDeliveryMethod(enabled=True, config=_WebAppDeliveryConfig())]
inputs = [
FormInput(
type=FormInputType.TEXT_INPUT,
ParagraphInputConfig(
output_variable_name="content",
default=FormInputDefault(type=PlaceholderType.CONSTANT, value="Enter content..."),
default=StringSource(type=ValueSourceType.CONSTANT, value="Enter content..."),
)
]
user_actions = [UserAction(id="submit", title="Submit", button_style=ButtonStyle.PRIMARY)]
user_actions = [UserActionConfig(id="submit", title="Submit", button_style=ButtonStyle.PRIMARY)]
node_data = HumanInputNodeData(
title="Human Input Test",
@ -338,8 +342,8 @@ class TestHumanInputNodeData:
def test_duplicate_input_output_variable_name_raises_validation_error(self):
"""Duplicate form input output_variable_name should raise validation error."""
duplicate_inputs = [
FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="content"),
FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="content"),
ParagraphInputConfig(output_variable_name="content"),
ParagraphInputConfig(output_variable_name="content"),
]
with pytest.raises(ValidationError, match="duplicated output_variable_name 'content'"):
@ -348,8 +352,8 @@ class TestHumanInputNodeData:
def test_duplicate_user_action_ids_raise_validation_error(self):
"""Duplicate user action ids should raise validation error."""
duplicate_actions = [
UserAction(id="submit", title="Submit"),
UserAction(id="submit", title="Submit Again"),
UserActionConfig(id="submit", title="Submit"),
UserActionConfig(id="submit", title="Submit Again"),
]
with pytest.raises(ValidationError, match="duplicated user action id 'submit'"):
@ -458,18 +462,16 @@ class TestHumanInputNodeVariableResolution:
title="Human Input",
form_content="Provide your name",
inputs=[
FormInput(
type=FormInputType.TEXT_INPUT,
ParagraphInputConfig(
output_variable_name="user_name",
default=FormInputDefault(type=PlaceholderType.VARIABLE, selector=["start", "name"]),
default=StringSource(type=ValueSourceType.VARIABLE, selector=["start", "name"]),
),
FormInput(
type=FormInputType.TEXT_INPUT,
ParagraphInputConfig(
output_variable_name="user_email",
default=FormInputDefault(type=PlaceholderType.CONSTANT, value="foo@example.com"),
default=StringSource(type=ValueSourceType.CONSTANT, value="foo@example.com"),
),
],
user_actions=[UserAction(id="submit", title="Submit")],
user_actions=[UserActionConfig(id="submit", title="Submit")],
)
config = {"id": "human", "data": node_data.model_dump()}
@ -534,7 +536,7 @@ class TestHumanInputNodeVariableResolution:
title="Human Input",
form_content="Provide your name",
inputs=[],
user_actions=[UserAction(id="submit", title="Submit")],
user_actions=[UserActionConfig(id="submit", title="Submit")],
)
config = {"id": "human", "data": node_data.model_dump()}
@ -661,7 +663,7 @@ class TestHumanInputNodeVariableResolution:
title="Human Input",
form_content="Provide your name",
inputs=[],
user_actions=[UserAction(id="submit", title="Submit")],
user_actions=[UserActionConfig(id="submit", title="Submit")],
delivery_methods=[
EmailDeliveryMethod(
enabled=True,
@ -721,15 +723,17 @@ class TestValidation:
def test_invalid_form_input_type(self):
"""Test validation with invalid form input type."""
with pytest.raises(ValidationError):
FormInput(
type="invalid-type", # Invalid type
output_variable_name="test",
ParagraphInputConfig.model_validate(
{
"type": "invalid-type",
"output_variable_name": "test",
}
)
def test_invalid_button_style(self):
"""Test validation with invalid button style."""
with pytest.raises(ValidationError):
UserAction(
UserActionConfig(
id="test",
title="Test",
button_style="invalid-style", # Invalid style
@ -777,13 +781,8 @@ class TestHumanInputNodeRenderedContent:
node_data = HumanInputNodeData(
title="Human Input",
form_content="Name: {{#$output.name#}}",
inputs=[
FormInput(
type=FormInputType.TEXT_INPUT,
output_variable_name="name",
)
],
user_actions=[UserAction(id="approve", title="Approve")],
inputs=[ParagraphInputConfig(output_variable_name="name")],
user_actions=[UserActionConfig(id="approve", title="Approve")],
)
config = {"id": "human", "data": node_data.model_dump()}

View File

@ -6,15 +6,26 @@ from core.workflow.node_runtime import DifyHumanInputNodeRuntime
from core.workflow.system_variables import default_system_variables
from graphon.entities import GraphInitParams
from graphon.enums import BuiltinNodeTypes
from graphon.file import FileTransferMethod, FileType
from graphon.graph_events import (
NodeRunHumanInputFormFilledEvent,
NodeRunHumanInputFormTimeoutEvent,
NodeRunStartedEvent,
)
from graphon.nodes.human_input.entities import HumanInputNodeData
from graphon.nodes.human_input.entities import (
FileInputConfig,
FileListInputConfig,
HumanInputNodeData,
ParagraphInputConfig,
SelectInputConfig,
StringListSource,
UserActionConfig,
)
from graphon.nodes.human_input.enums import HumanInputFormStatus
from graphon.nodes.human_input.human_input_node import HumanInputNode
from graphon.runtime import GraphRuntimeState, VariablePool
from graphon.variables.segments import ArrayFileSegment, FileSegment, StringSegment
from graphon.variables.types import SegmentType
from libs.datetime_utils import naive_utc_now
@ -76,19 +87,15 @@ def _build_node(form_content: str = "Please enter your name:\n\n{{#$output.name#
"title": "Human Input",
"form_content": form_content,
"inputs": [
{
"type": "text_input",
"output_variable_name": "name",
"default": {"type": "constant", "value": ""},
}
],
"user_actions": [
{
"id": "Accept",
"title": "Approve",
"button_style": "default",
}
ParagraphInputConfig(output_variable_name="name").model_dump(mode="json"),
SelectInputConfig(
output_variable_name="decision",
option_source=StringListSource(type="constant", value=["approve", "reject"]),
).model_dump(mode="json"),
FileInputConfig(output_variable_name="attachment").model_dump(mode="json"),
FileListInputConfig(output_variable_name="attachments", number_limits=2).model_dump(mode="json"),
],
"user_actions": [UserActionConfig(id="Accept", title="Approve").model_dump(mode="json")],
},
}
@ -97,7 +104,28 @@ def _build_node(form_content: str = "Please enter your name:\n\n{{#$output.name#
rendered_content=form_content,
submitted=True,
selected_action_id="Accept",
submitted_data={"name": "Alice"},
submitted_data={
"name": "Alice",
"decision": "approve",
"attachment": {
"type": "document",
"transfer_method": "remote_url",
"remote_url": "https://example.com/resume.pdf",
"filename": "resume.pdf",
"extension": ".pdf",
"mime_type": "application/pdf",
},
"attachments": [
{
"type": "image",
"transfer_method": "remote_url",
"remote_url": "https://example.com/a.png",
"filename": "a.png",
"extension": ".png",
"mime_type": "image/png",
}
],
},
status=HumanInputFormStatus.SUBMITTED,
expiration_time=naive_utc_now() + datetime.timedelta(days=1),
)
@ -138,20 +166,8 @@ def _build_timeout_node() -> HumanInputNode:
"data": {
"title": "Human Input",
"form_content": "Please enter your name:\n\n{{#$output.name#}}",
"inputs": [
{
"type": "text_input",
"output_variable_name": "name",
"default": {"type": "constant", "value": ""},
}
],
"user_actions": [
{
"id": "Accept",
"title": "Approve",
"button_style": "default",
}
],
"inputs": [ParagraphInputConfig(output_variable_name="name").model_dump(mode="json")],
"user_actions": [UserActionConfig(id="Accept", title="Approve").model_dump(mode="json")],
},
}

View File

@ -4,7 +4,7 @@ from dataclasses import dataclass, field
from datetime import datetime, timedelta
from typing import Any
from graphon.nodes.human_input.entities import FormInput
from graphon.nodes.human_input.entities import FormInputConfig
from graphon.nodes.human_input.enums import TimeoutUnit
from libs.datetime_utils import naive_utc_now
@ -45,7 +45,7 @@ class HumanInputForm:
tenant_id: str
app_id: str | None
form_content: str
inputs: list[FormInput]
inputs: list[FormInputConfig]
user_actions: list[dict[str, Any]]
timeout: int
timeout_unit: TimeoutUnit
@ -88,7 +88,7 @@ class HumanInputForm:
def to_response_dict(self, *, include_site_info: bool) -> dict[str, Any]:
inputs_response = [
{
"type": form_input.type.name.lower().replace("_", "-"),
"type": form_input.type.value,
"output_variable_name": form_input.output_variable_name,
}
for form_input in self.inputs

View File

@ -7,11 +7,10 @@ from datetime import timedelta
import pytest
from graphon.nodes.human_input.entities import (
FormInput,
UserAction,
ParagraphInputConfig,
UserActionConfig,
)
from graphon.nodes.human_input.enums import (
FormInputType,
TimeoutUnit,
)
from libs.datetime_utils import naive_utc_now
@ -50,8 +49,8 @@ class TestFormService:
"tenant_id": "tenant-abc",
"app_id": "app-def",
"form_content": "# Test Form\n\nInput: {{#$output.input#}}",
"inputs": [FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="input", default=None)],
"user_actions": [UserAction(id="submit", title="Submit")],
"inputs": [ParagraphInputConfig(output_variable_name="input")],
"user_actions": [UserActionConfig(id="submit", title="Submit")],
"timeout": 1,
"timeout_unit": TimeoutUnit.HOUR,
"form_token": "token-xyz",
@ -304,8 +303,8 @@ class TestFormValidation:
"tenant_id": "tenant-abc",
"app_id": "app-def",
"form_content": "Test form",
"inputs": [FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="required_input", default=None)],
"user_actions": [UserAction(id="submit", title="Submit")],
"inputs": [ParagraphInputConfig(output_variable_name="required_input")],
"user_actions": [UserActionConfig(id="submit", title="Submit")],
"timeout": 1,
"timeout_unit": TimeoutUnit.HOUR,
}

View File

@ -7,11 +7,10 @@ from datetime import datetime, timedelta
import pytest
from graphon.nodes.human_input.entities import (
FormInput,
UserAction,
ParagraphInputConfig,
UserActionConfig,
)
from graphon.nodes.human_input.enums import (
FormInputType,
TimeoutUnit,
)
from libs.datetime_utils import naive_utc_now
@ -32,8 +31,8 @@ class TestHumanInputForm:
"tenant_id": "tenant-abc",
"app_id": "app-def",
"form_content": "# Test Form\n\nInput: {{#$output.input#}}",
"inputs": [FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="input", default=None)],
"user_actions": [UserAction(id="submit", title="Submit")],
"inputs": [ParagraphInputConfig(output_variable_name="input")],
"user_actions": [UserActionConfig(id="submit", title="Submit")],
"timeout": 2,
"timeout_unit": TimeoutUnit.HOUR,
"form_token": "token-xyz",
@ -132,7 +131,7 @@ class TestHumanInputForm:
assert "site" not in response
assert response["form_content"] == "# Test Form\n\nInput: {{#$output.input#}}"
assert len(response["inputs"]) == 1
assert response["inputs"][0]["type"] == "text-input"
assert response["inputs"][0]["type"] == "paragraph"
assert response["inputs"][0]["output_variable_name"] == "input"
def test_form_to_response_dict_with_site_info(self, sample_form_data):

View File

@ -9,12 +9,17 @@ from core.repositories.human_input_repository import (
HumanInputFormRecord,
HumanInputFormSubmissionRepository,
)
from graphon.file import File, FileTransferMethod, FileType
from graphon.nodes.human_input.entities import (
FileInputConfig,
FileListInputConfig,
FormDefinition,
FormInput,
UserAction,
ParagraphInputConfig,
SelectInputConfig,
StringListSource,
UserActionConfig,
)
from graphon.nodes.human_input.enums import FormInputType, HumanInputFormKind, HumanInputFormStatus
from graphon.nodes.human_input.enums import HumanInputFormKind, HumanInputFormStatus, ValueSourceType
from libs.datetime_utils import naive_utc_now
from models.human_input import RecipientType
from services.human_input_service import (
@ -50,7 +55,7 @@ def sample_form_record():
definition=FormDefinition(
form_content="hello",
inputs=[],
user_actions=[UserAction(id="submit", title="Submit")],
user_actions=[UserActionConfig(id="submit", title="Submit")],
rendered_content="<p>hello</p>",
expiration_time=naive_utc_now() + timedelta(hours=1),
),
@ -273,7 +278,7 @@ def test_submit_form_by_token_missing_inputs(sample_form_record, mock_session_fa
definition_with_input = FormDefinition(
form_content="hello",
inputs=[FormInput(type=FormInputType.TEXT_INPUT, output_variable_name="content")],
inputs=[ParagraphInputConfig(output_variable_name="content")],
user_actions=sample_form_record.definition.user_actions,
rendered_content="<p>hello</p>",
expiration_time=sample_form_record.expiration_time,