167 lines
5.8 KiB
Python
167 lines
5.8 KiB
Python
|
|
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
|