from __future__ import annotations import pytest from yuxi.channels.adapters.slack.blocks import ( build_actions, build_approval_blocks, build_button, build_divider, build_error_notice, build_poll_blocks, build_section, ) class TestBuildSection: def test_basic_section(self): block = build_section("Hello World") assert block["type"] == "section" assert block["text"]["type"] == "mrkdwn" assert block["text"]["text"] == "Hello World" assert "accessory" not in block def test_with_accessory(self): accessory = {"type": "button", "text": {"type": "plain_text", "text": "Click"}} block = build_section("Hello", accessory=accessory) assert block["accessory"] == accessory class TestBuildDivider: def test_divider(self): assert build_divider() == {"type": "divider"} class TestBuildButton: def test_default_button(self): btn = build_button("Click me", "action_1") assert btn["type"] == "button" assert btn["text"]["text"] == "Click me" assert btn["action_id"] == "action_1" assert "value" not in btn assert "style" not in btn def test_with_value(self): btn = build_button("Click", "action_1", value="val1") assert btn["value"] == "val1" def test_primary_style(self): btn = build_button("Submit", "submit", style="primary") assert btn["style"] == "primary" def test_danger_style(self): btn = build_button("Delete", "delete", style="danger") assert btn["style"] == "danger" def test_invalid_style_ignored(self): btn = build_button("Click", "action_1", style="custom") assert "style" not in btn class TestBuildActions: def test_single_button(self): btn = build_button("OK", "ok_btn") actions = build_actions(btn) assert actions["type"] == "actions" assert len(actions["elements"]) == 1 assert actions["elements"][0] == btn def test_multiple_buttons(self): btn1 = build_button("Yes", "yes") btn2 = build_button("No", "no") actions = build_actions(btn1, btn2) assert len(actions["elements"]) == 2 class TestBuildApprovalBlocks: def test_approval_defaults(self): blocks = build_approval_blocks("审批请求", "详细信息") assert len(blocks) == 4 assert blocks[0]["type"] == "header" assert blocks[0]["text"]["text"] == "审批请求" assert blocks[1]["type"] == "section" assert blocks[1]["text"]["text"] == "详细信息" assert blocks[2]["type"] == "divider" assert blocks[3]["type"] == "actions" elements = blocks[3]["elements"] assert elements[0]["action_id"] == "exec_approve" assert elements[0]["style"] == "primary" assert elements[0]["text"]["text"] == "确认执行" assert elements[1]["action_id"] == "exec_reject" assert elements[1]["style"] == "danger" assert elements[1]["text"]["text"] == "取消" def test_approval_custom_action_ids(self): blocks = build_approval_blocks("审批", "详情", confirm_action_id="custom_approve", reject_action_id="custom_reject") elements = blocks[3]["elements"] assert elements[0]["action_id"] == "custom_approve" assert elements[1]["action_id"] == "custom_reject" def test_approval_custom_button_text(self): blocks = build_approval_blocks("审批", "详情", confirm_text="Yes", reject_text="No") elements = blocks[3]["elements"] assert elements[0]["text"]["text"] == "Yes" assert elements[1]["text"]["text"] == "No" class TestBuildPollBlocks: def test_poll_blocks(self): blocks = build_poll_blocks("你喜欢什么颜色?", ["红色", "蓝色", "绿色"], "poll_001") assert blocks[0]["type"] == "header" assert blocks[0]["text"]["text"] == "📊 投票" assert blocks[1]["text"]["text"] == "*你喜欢什么颜色?*" assert blocks[2]["type"] == "divider" option_blocks = blocks[3:] assert len(option_blocks) == 3 for i, block in enumerate(option_blocks): assert block["type"] == "section" assert block["accessory"]["action_id"] == f"poll_poll_001_{i}" assert block["accessory"]["value"] == str(i) class TestBuildErrorNotice: def test_error_notice(self): blocks = build_error_notice("发生了错误") assert len(blocks) == 2 assert blocks[0]["type"] == "section" assert "错误" in blocks[0]["text"]["text"] assert "发生了错误" in blocks[0]["text"]["text"] assert blocks[1]["type"] == "context" assert len(blocks[1]["elements"]) == 1