from session_bot.render import build_channel_text from session_bot.html_entities import html_to_text_entities def test_build_channel_text_includes_phrase() -> None: config = { "template_text": "{{hidden_link}}\nheader\n\n{{actors}}", "hidden_link_url": "https://example.com/image.png", "actors": [ { "key": "astat", "display_name": "ASTAT", "display_html": "ASTAT", "link": "https://t.me/example", "pronouns": "he/him", "meta_html": " he/him ", "emoji": "🌟", "default_status": "backstage", "phrases": {"open": "принимает тейки"}, } ], } state = {"actors": {"astat": {"status": "open", "phrase": "готов к игре"}}} text = build_channel_text(config, state) assert not text.startswith('') assert 'ASTAT' in text assert "готов к игре" in text def test_build_channel_text_can_prefix_hidden_link() -> None: config = { "template_text": "header\n\n{{actors}}", "hidden_link_url": "https://example.com/image.png", "hidden_link_char": "​", "actors": [], } text = build_channel_text(config, {"actors": {}}, include_hidden_link=True) assert text.startswith('') def test_build_channel_text_supports_per_actor_placeholders() -> None: config = { "template_text": "HEAD\n\n{{actor:astat}}\n\nMID\n\n{{actor:mari}}\n\nTAIL", "actors": [ { "key": "astat", "display_name": "ASTAT", "display_html": "ASTAT", "link": "https://t.me/astat", "pronouns": "he/him", "meta_html": " he/him ", "emoji": "🌟", "default_status": "backstage", "phrases": {"backstage": "в закулисье."}, }, { "key": "mari", "display_name": "MARI", "display_html": "MARI", "link": "https://t.me/mari", "pronouns": "she/her", "meta_html": " she/her ", "emoji": "🌟", "default_status": "open", "phrases": {"open": "исполняет роль."}, }, ], } text = build_channel_text(config, {"actors": {}}) assert text.count("ASTAT") == 1 assert text.count("MARI") == 1 def test_build_channel_text_inlines_actor_fragment_without_duplication() -> None: config = { "template_text": ( '🌟 LIEBE she/her {{actor:liebe}}\n' '🌟 VICTOR tech bot' ), "actors": [ { "key": "liebe", "display_name": "LIEBE", "display_html": "LIEBE", "link": "https://t.me/liebe", "pronouns": "she/her", "meta_html": " she/her ", "emoji": "🌟", "default_status": "backstage", "phrases": {"backstage": "в закулисье."}, } ], } text = build_channel_text(config, {"actors": {}}) assert text.count("LIEBE") == 1 assert "she/her в закулисье." in text def test_plain_links_are_converted_to_html() -> None: config = { "template_text": "rules (https://example.com)\n\n{{actors}}", "actors": [ { "key": "astat", "display_name": "ASTAT", "display_html": "ASTAT", "link": "https://t.me/astat", "pronouns": "he/him", "meta_html": " he/him ", "emoji": "🌟", "default_status": "backstage", "phrases": {"backstage": "в закулисье."}, } ], } text = build_channel_text(config, {"actors": {}}) assert 'rules' in text def test_html_to_text_entities_supports_custom_emoji_and_links() -> None: text, entities = html_to_text_entities( '🌟 rules' ) assert text == "🌟 rules" assert any(entity.type == "custom_emoji" and entity.custom_emoji_id == "123" for entity in entities) assert any(entity.type == "text_link" and entity.url == "https://example.com" for entity in entities)