ForcePilot/backend/test/unit/channels/test_twitch_normalizer.py

167 lines
5.8 KiB
Python
Raw Normal View History

from __future__ import annotations
import pytest
from yuxi.channels.adapters.twitch.normalizer import (
normalize_irc_message,
resolve_mentions,
)
from yuxi.channels.adapters.twitch.irc_parser import ParsedIRCMessage
from yuxi.channels.models import (
ChatType,
EventType,
MessageType,
)
def make_parsed(command="PRIVMSG", tags=None, prefix="user!user@host", params=None, trailing=""):
return ParsedIRCMessage(
command=command,
prefix=prefix,
params=params or ["#test_channel"],
trailing=trailing,
tags=tags or {"user-id": "123", "display-name": "TestUser", "tmi-sent-ts": "1600000000000"},
raw="",
)
class TestNormalizePrivmsg:
def test_basic_message(self):
parsed = make_parsed(trailing="Hello world")
msg = normalize_irc_message(parsed)
assert msg is not None
assert msg.content == "Hello world"
assert msg.event_type == EventType.MESSAGE_RECEIVED
assert msg.message_type == MessageType.TEXT
assert msg.chat_type == ChatType.GROUP
assert msg.identity.channel_id == "twitch"
assert msg.identity.channel_chat_id == "#test_channel"
def test_message_with_bits(self):
tags = {"user-id": "123", "display-name": "TestUser", "tmi-sent-ts": "1600000000000", "bits": "500"}
parsed = make_parsed(tags=tags, trailing="Cheer500")
msg = normalize_irc_message(parsed)
assert msg is not None
assert msg.metadata["bits"] == 500
def test_message_with_mod(self):
tags = {"user-id": "123", "display-name": "TestUser", "tmi-sent-ts": "1600000000000", "mod": "1"}
parsed = make_parsed(tags=tags, trailing="hello")
msg = normalize_irc_message(parsed)
assert msg is not None
assert msg.metadata["is_mod"] is True
def test_message_with_badges(self):
tags = {
"user-id": "123",
"display-name": "TestUser",
"tmi-sent-ts": "1600000000000",
"badges": "subscriber/6,broadcaster/1",
}
parsed = make_parsed(tags=tags, trailing="hello")
msg = normalize_irc_message(parsed)
assert msg is not None
assert "subscriber" in msg.metadata["badges"]
def test_message_with_display_name(self):
tags = {"user-id": "123", "display-name": "CoolUser", "tmi-sent-ts": "1600000000000"}
parsed = make_parsed(tags=tags, trailing="hello")
msg = normalize_irc_message(parsed)
assert msg is not None
assert msg.metadata["display_name"] == "CoolUser"
class TestNormalizeUsernotice:
def test_subscription(self):
tags = {
"user-id": "456",
"display-name": "Subber",
"msg-id": "sub",
"msg-param-sub-plan": "2000",
}
parsed = make_parsed(command="USERNOTICE", tags=tags, prefix="subber!subber@host")
msg = normalize_irc_message(parsed)
assert msg is not None
assert msg.event_type == EventType.SYSTEM_EVENT
assert msg.metadata["event"] == "subscription"
def test_raid(self):
tags = {
"user-id": "789",
"display-name": "Raider",
"msg-id": "raid",
"msg-param-viewerCount": "42",
}
parsed = make_parsed(command="USERNOTICE", tags=tags, prefix="raider!raider@host")
msg = normalize_irc_message(parsed)
assert msg is not None
assert msg.metadata["event"] == "raid"
assert msg.metadata["msg_param_viewer_count"] == "42"
class TestNormalizeClearchat:
def test_timeout(self):
tags = {"target-user-id": "999", "ban-duration": "300"}
parsed = make_parsed(command="CLEARCHAT", tags=tags, trailing="banned_user")
msg = normalize_irc_message(parsed)
assert msg is not None
assert msg.event_type == EventType.MESSAGE_DELETED
assert msg.metadata["ban_duration_sec"] == 300
def test_no_target(self):
parsed = make_parsed(command="CLEARCHAT", tags={})
msg = normalize_irc_message(parsed)
assert msg is not None
assert msg.event_type == EventType.MESSAGE_DELETED
class TestNormalizeNotice:
def test_roomstate_notice_filtered(self):
tags = {"msg-id": "slow_on"}
parsed = make_parsed(command="NOTICE", tags=tags, trailing="slow mode on")
msg = normalize_irc_message(parsed)
assert msg is None
def test_other_notice(self):
tags = {"msg-id": "some_custom_msg"}
parsed = make_parsed(command="NOTICE", tags=tags, trailing="custom notice")
msg = normalize_irc_message(parsed)
assert msg is not None
assert msg.event_type == EventType.SYSTEM_EVENT
class TestNormalizeSkipCommands:
def test_join_skipped(self):
parsed = make_parsed(command="JOIN")
assert normalize_irc_message(parsed) is None
def test_part_skipped(self):
parsed = make_parsed(command="PART")
assert normalize_irc_message(parsed) is None
def test_roomstate_skipped(self):
parsed = make_parsed(command="ROOMSTATE")
assert normalize_irc_message(parsed) is None
def test_ping_skipped(self):
parsed = make_parsed(command="PING")
assert normalize_irc_message(parsed) is None
class TestResolveMentions:
def test_single_mention(self):
mentions = resolve_mentions("hello @alice")
assert "alice" in mentions.mentioned_user_ids
def test_multiple_mentions(self):
mentions = resolve_mentions("@alice @bob hi")
assert "alice" in mentions.mentioned_user_ids
assert "bob" in mentions.mentioned_user_ids
def test_no_mentions(self):
mentions = resolve_mentions("hello world")
assert mentions.mentioned_user_ids == []
def test_mention_with_punctuation(self):
mentions = resolve_mentions("hey @user, what's up?")
assert "user" in mentions.mentioned_user_ids