mirror of
https://github.com/langgenius/dify.git
synced 2026-11-11 22:02:23 +08:00
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:
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"}
|
||||
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in new issue
Block a user