diff --git a/api/tests/unit_tests/core/workflow/test_human_input_adapter.py b/api/tests/unit_tests/core/workflow/test_human_input_adapter.py
index 1e8ee1d5240..1ce4a7a1d50 100644
--- a/api/tests/unit_tests/core/workflow/test_human_input_adapter.py
+++ b/api/tests/unit_tests/core/workflow/test_human_input_adapter.py
@@ -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 "Bold" in rendered
assert 'link' in rendered
-def test_render_markdown_body_sanitizes_unsafe_html():
+def test_render_markdown_body_sanitizes_unsafe_html() -> None:
rendered = EmailDeliveryConfig.render_markdown_body(
'Click'
)
@@ -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 'ok' 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("raw html and **markdown**")
assert "" not in rendered
@@ -73,7 +75,7 @@ def test_render_markdown_body_does_not_allow_raw_html_tags():
assert "markdown" 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 "" 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("Alert
")
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"}
diff --git a/api/tests/unit_tests/pyrefly.toml b/api/tests/unit_tests/pyrefly.toml
index 4f8b5a9d1ae..213ebe27ef7 100644
--- a/api/tests/unit_tests/pyrefly.toml
+++ b/api/tests/unit_tests/pyrefly.toml
@@ -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",