test(api): bring the human input adapter tests under strict pyrefly (#45819)

Co-authored-by: yetuge <yetuge@users.noreply.github.com>
This commit is contained in:
yetugeandyetuge authored and GitHub committed 2026-11-08 17:22:26 +00:00
1 parent 55a01879d7
commit 3e4e040ae0
2 files changed
+20 -27

No files matched your search

@@ -4,10 +4,12 @@ import pytest
from pydantic import BaseModel
from core.workflow.human_input_adapter import (
BoundRecipient,
DeliveryMethodType,
EmailDeliveryConfig,
EmailDeliveryMethod,
EmailRecipients,
ExternalRecipient,
InstantMessageDeliveryMethod,
InstantMessageProvider,
InstantMessageRecipientType,
@@ -24,7 +26,7 @@ from graphon.nodes.base.variable_template_parser import VariableTemplateParser
from graphon.runtime import VariablePool
def test_render_body_template_replaces_variable_values():
def test_render_body_template_replaces_variable_values() -> None:
config = EmailDeliveryConfig(
recipients=EmailRecipients(),
subject="Subject",
@@ -38,14 +40,14 @@ def test_render_body_template_replaces_variable_values():
assert result == "Hello World https://example.com"
def test_render_markdown_body_renders_markdown_to_html():
def test_render_markdown_body_renders_markdown_to_html() -> None:
rendered = EmailDeliveryConfig.render_markdown_body("**Bold** and [link](https://example.com)")
assert "<strong>Bold</strong>" in rendered
assert '<a href="https://example.com">link</a>' in rendered
def test_render_markdown_body_sanitizes_unsafe_html():
def test_render_markdown_body_sanitizes_unsafe_html() -> None:
rendered = EmailDeliveryConfig.render_markdown_body(
'<script>alert("xss")</script><a href="javascript:alert(1)" onclick="alert(2)">Click</a>'
)
@@ -57,7 +59,7 @@ def test_render_markdown_body_sanitizes_unsafe_html():
assert "Click" in rendered
def test_render_markdown_body_sanitizes_markdown_link_with_javascript_href():
def test_render_markdown_body_sanitizes_markdown_link_with_javascript_href() -> None:
rendered = EmailDeliveryConfig.render_markdown_body("[bad](javascript:alert(1)) and [ok](https://example.com)")
assert "javascript:" not in rendered
@@ -65,7 +67,7 @@ def test_render_markdown_body_sanitizes_markdown_link_with_javascript_href():
assert '<a href="https://example.com">ok</a>' in rendered
def test_render_markdown_body_does_not_allow_raw_html_tags():
def test_render_markdown_body_does_not_allow_raw_html_tags() -> None:
rendered = EmailDeliveryConfig.render_markdown_body("<b>raw html</b> and **markdown**")
assert "<b>" not in rendered
@@ -73,7 +75,7 @@ def test_render_markdown_body_does_not_allow_raw_html_tags():
assert "<strong>markdown</strong>" in rendered
def test_render_markdown_body_supports_table_syntax():
def test_render_markdown_body_supports_table_syntax() -> None:
rendered = EmailDeliveryConfig.render_markdown_body("| h1 | h2 |\n| --- | ---: |\n| v1 | v2 |")
assert "<table>" in rendered
@@ -83,7 +85,7 @@ def test_render_markdown_body_supports_table_syntax():
assert "style=" not in rendered
def test_sanitize_subject_removes_crlf():
def test_sanitize_subject_removes_crlf() -> None:
sanitized = EmailDeliveryConfig.sanitize_subject("Notice\r\nBCC:attacker@example.com")
assert "\r" not in sanitized
@@ -91,7 +93,7 @@ def test_sanitize_subject_removes_crlf():
assert sanitized == "Notice BCC:attacker@example.com"
def test_sanitize_subject_removes_html_tags():
def test_sanitize_subject_removes_html_tags() -> None:
sanitized = EmailDeliveryConfig.sanitize_subject("<b>Alert</b><img src=x onerror=1>")
assert "<" not in sanitized
@@ -169,9 +171,14 @@ def test_parse_human_input_delivery_methods_normalizes_legacy_recipient_keys() -
)
assert len(methods) == 1
assert methods[0].config.recipients.include_bound_group is True
assert methods[0].config.recipients.items[0].reference_id == "user-1"
assert methods[0].config.recipients.items[1].email == "external@example.com"
config = methods[0].config
assert isinstance(config, EmailDeliveryConfig)
assert config.recipients.include_bound_group is True
bound_recipient, external_recipient = config.recipients.items
assert isinstance(bound_recipient, BoundRecipient)
assert isinstance(external_recipient, ExternalRecipient)
assert bound_recipient.reference_id == "user-1"
assert external_recipient.email == "external@example.com"
def test_parse_human_input_delivery_methods_returns_empty_for_non_lists() -> None:
@@ -373,7 +380,7 @@ def test_adapt_node_config_for_graph_rewrites_nested_node_data() -> None:
def test_adapt_human_input_node_data_for_graph_accepts_models() -> None:
class _NodeModel(BaseModel):
delivery_methods: list[dict]
delivery_methods: list[dict[str, object]]
normalized = adapt_human_input_node_data_for_graph(
_NodeModel(
@@ -390,11 +397,6 @@ def test_adapt_human_input_node_data_for_graph_accepts_models() -> None:
assert normalized["delivery_methods"][0]["type"] == DeliveryMethodType.WEBAPP
def test_adapt_human_input_node_data_for_graph_rejects_non_mappings() -> None:
with pytest.raises(TypeError, match="human-input node data must be a mapping"):
adapt_human_input_node_data_for_graph(123)
def test_adapt_human_input_node_data_for_graph_preserves_non_mapping_methods() -> None:
normalized = adapt_human_input_node_data_for_graph(
{
@@ -478,15 +480,7 @@ def test_webapp_delivery_method_uses_empty_selector_set() -> None:
assert method.extract_variable_selectors() == ()
def test_adapt_node_data_for_graph_rejects_non_mappings() -> None:
with pytest.raises(TypeError, match="node data must be a mapping"):
adapt_node_data_for_graph(123)
def test_adapt_node_config_for_graph_rejects_non_mapping_and_preserves_raw_data() -> None:
with pytest.raises(TypeError, match="node config must be a mapping"):
adapt_node_config_for_graph(123)
def test_adapt_node_config_for_graph_preserves_raw_data() -> None:
assert adapt_node_config_for_graph({"data": "raw"}) == {"data": "raw"}
-1
View File
@@ -199,7 +199,6 @@ project-excludes = [
"../e2e_tests/contracts/core/workflow/nodes/http_request/test_http_request_executor.py",
"../e2e_tests/contracts/core/workflow/nodes/http_request/test_http_request_node.py",
"core/workflow/nodes/human_input/test_entities.py",
"core/workflow/test_human_input_adapter.py",
"core/workflow/nodes/knowledge_index/test_knowledge_index_node.py",
"core/workflow/nodes/knowledge_retrieval/test_knowledge_retrieval_node.py",
"../helpers/unit/core/workflow/nodes/list_operator/node_spec.py",