Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: improve chat regex matching (#616)
* fix: improve chat regex matching * chore: add unit tests for parseBadges * chore: add unit test for whisper parsing * chore: add unit test for privmsg parsing * chore: add unit test for clearmsg parsing * chore: add unit test for clearchat parsing * chore: add unit test for globaluserstate parsing * fix: use display name when login and client are missing * chore: add unit test for notice parsing * chore: add unit test for reconnect parsing * chore: add unit test for roomstate parsing * chore: add unit test for usernotice parsing * chore: add unit test for userstate parsing
- Loading branch information
Showing
4 changed files
with
198 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
149 changes: 149 additions & 0 deletions
149
chat/src/test/java/com/github/twitch4j/chat/events/channel/IRCMessageEventTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package com.github.twitch4j.chat.events.channel; | ||
|
||
import com.github.twitch4j.common.enums.CommandPermission; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Tag; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.Collections; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
||
@Tag("unittest") | ||
public class IRCMessageEventTest { | ||
|
||
@Test | ||
@DisplayName("Tests that CLEARCHAT is parsed by IRCMessageEvent") | ||
void parseChatClear() { | ||
IRCMessageEvent e = build("@room-id=12345678;tmi-sent-ts=1642715756806 :tmi.twitch.tv CLEARCHAT #dallas"); | ||
|
||
assertEquals("CLEARCHAT", e.getCommandType()); | ||
assertEquals("dallas", e.getChannelName().orElse(null)); | ||
assertEquals("12345678", e.getChannelId()); | ||
} | ||
|
||
@Test | ||
@DisplayName("Tests that CLEARMSG is parsed by IRCMessageEvent") | ||
void parseMessageDeletion() { | ||
IRCMessageEvent e = build("@login=foo;room-id=;target-msg-id=94e6c7ff-bf98-4faa-af5d-7ad633a158a9;tmi-sent-ts=1642720582342 :tmi.twitch.tv CLEARMSG #bar :what a great day"); | ||
|
||
assertEquals("foo", e.getUserName()); | ||
assertEquals("bar", e.getChannelName().orElse(null)); | ||
assertEquals("CLEARMSG", e.getCommandType()); | ||
assertEquals("what a great day", e.getMessage().orElse(null)); | ||
assertEquals("94e6c7ff-bf98-4faa-af5d-7ad633a158a9", e.getTagValue("target-msg-id").orElse(null)); | ||
} | ||
|
||
@Test | ||
@DisplayName("Tests that GLOBALUSERSTATE is parsed by IRCMessageEvent") | ||
void parseGlobalUserState() { | ||
IRCMessageEvent e = build("@badge-info=subscriber/8;badges=subscriber/6;color=#0D4200;display-name=dallas;emote-sets=0,33,50,237,793,2126,3517,4578,5569,9400,10337,12239;turbo=0;user-id=12345678;user-type=admin " + | ||
":tmi.twitch.tv GLOBALUSERSTATE"); | ||
|
||
assertEquals("GLOBALUSERSTATE", e.getCommandType()); | ||
assertEquals("12345678", e.getUserId()); | ||
assertEquals("dallas", e.getTagValue("display-name").orElse(null)); | ||
assertEquals("dallas", e.getUserName()); | ||
assertEquals("0,33,50,237,793,2126,3517,4578,5569,9400,10337,12239", e.getTagValue("emote-sets").orElse(null)); | ||
} | ||
|
||
@Test | ||
@DisplayName("Test that normal messages are parsed by IRCMessageEvent") | ||
void parseMessage() { | ||
IRCMessageEvent e = build("@badge-info=;badges=broadcaster/1;client-nonce=459e3142897c7a22b7d275178f2259e0;color=#0000FF;display-name=lovingt3s;emote-only=1;emotes=62835:0-10;first-msg=0;flags=;" + | ||
"id=885196de-cb67-427a-baa8-82f9b0fcd05f;mod=0;room-id=713936733;subscriber=0;tmi-sent-ts=1643904084794;turbo=0;user-id=713936733;user-type= " + | ||
":lovingt3s!lovingt3s@lovingt3s.tmi.twitch.tv PRIVMSG #lovingt3s :bleedPurple"); | ||
|
||
assertEquals("bleedPurple", e.getMessage().orElse(null)); | ||
assertEquals("lovingt3s", e.getChannelName().orElse(null)); | ||
assertEquals("713936733", e.getChannelId()); | ||
assertEquals("713936733", e.getUserId()); | ||
assertEquals("lovingt3s", e.getUserName()); | ||
assertEquals("PRIVMSG", e.getCommandType()); | ||
assertTrue(e.getClientPermissions().contains(CommandPermission.BROADCASTER)); | ||
assertEquals("885196de-cb67-427a-baa8-82f9b0fcd05f", e.getMessageId().orElse(null)); | ||
assertEquals("459e3142897c7a22b7d275178f2259e0", e.getNonce().orElse(null)); | ||
assertEquals("62835:0-10", e.getTagValue("emotes").orElse(null)); | ||
} | ||
|
||
@Test | ||
@DisplayName("Tests that NOTICE is parsed by IRCMessageEvent") | ||
void parseNotice() { | ||
IRCMessageEvent e = build("@msg-id=delete_message_success :tmi.twitch.tv NOTICE #bar :The message from foo is now deleted."); | ||
|
||
assertEquals("NOTICE", e.getCommandType()); | ||
assertEquals("bar", e.getChannelName().orElse(null)); | ||
assertEquals("delete_message_success", e.getTags().get("msg-id")); | ||
assertEquals("The message from foo is now deleted.", e.getMessage().orElse(null)); | ||
} | ||
|
||
@Test | ||
@DisplayName("Tests that RECONNECT is parsed by IRCMessageEvent") | ||
void parseReconnect() { | ||
IRCMessageEvent e = build(":tmi.twitch.tv RECONNECT"); | ||
assertEquals("RECONNECT", e.getCommandType()); | ||
} | ||
|
||
@Test | ||
@DisplayName("Tests that ROOMSTATE is parsed by IRCMessageEvent") | ||
void parseRoomState() { | ||
IRCMessageEvent e = build("@emote-only=0;followers-only=-1;r9k=0;rituals=0;room-id=12345678;slow=0;subs-only=0 :tmi.twitch.tv ROOMSTATE #bar"); | ||
assertEquals("ROOMSTATE", e.getCommandType()); | ||
assertEquals("bar", e.getChannelName().orElse(null)); | ||
assertEquals("12345678", e.getChannelId()); | ||
assertEquals("0", e.getTags().get("emote-only")); | ||
assertEquals("-1", e.getTags().get("followers-only")); | ||
} | ||
|
||
@Test | ||
@DisplayName("Tests that USERNOTICE is parsed by IRCMessageEvent") | ||
void parseUserNotice() { | ||
IRCMessageEvent e = build("@badge-info=;badges=staff/1,premium/1;color=#0000FF;display-name=TWW2;emotes=;id=e9176cd8-5e22-4684-ad40-ce53c2561c5e;login=tww2;mod=0;msg-id=subgift;" + | ||
"msg-param-months=1;msg-param-recipient-display-name=Mr_Woodchuck;msg-param-recipient-id=55554444;msg-param-recipient-name=mr_woodchuck;msg-param-sub-plan-name=House\\sof\\sNyoro~n;msg-param-sub-plan=1000;" + | ||
"room-id=12345678;subscriber=0;system-msg=TWW2\\sgifted\\sa\\sTier\\s1\\ssub\\sto\\sMr_Woodchuck!;tmi-sent-ts=1521159445153;turbo=0;user-id=87654321;user-type=staff :tmi.twitch.tv USERNOTICE #forstycup"); | ||
|
||
assertEquals("USERNOTICE", e.getCommandType()); | ||
assertEquals("12345678", e.getChannelId()); | ||
assertEquals("forstycup", e.getChannelName().orElse(null)); | ||
assertEquals("87654321", e.getUserId()); | ||
assertEquals("TWW2 gifted a Tier 1 sub to Mr_Woodchuck!", e.getTagValue("system-msg").orElse(null)); | ||
assertEquals("TWW2", e.getTagValue("display-name").orElse(null)); | ||
assertEquals("tww2", e.getUserName()); | ||
assertEquals("subgift", e.getTagValue("msg-id").orElse(null)); | ||
} | ||
|
||
@Test | ||
@DisplayName("Tests that USERSTATE is parsed by IRCMessageEevent") | ||
void parseUserState() { | ||
IRCMessageEvent e = build("@badge-info=;badges=staff/1;color=#0D4200;display-name=ronni;emote-sets=0,33,50,237,793,2126,3517,4578,5569,9400,10337,12239;mod=1;subscriber=1;turbo=1;user-type=staff " + | ||
":tmi.twitch.tv USERSTATE #dallas"); | ||
|
||
assertEquals("USERSTATE", e.getCommandType()); | ||
assertEquals("dallas", e.getChannelName().orElse(null)); | ||
assertEquals("ronni", e.getUserName()); | ||
assertEquals("0,33,50,237,793,2126,3517,4578,5569,9400,10337,12239", e.getTagValue("emote-sets").orElse(null)); | ||
assertTrue(e.getClientPermissions().contains(CommandPermission.TWITCHSTAFF)); | ||
} | ||
|
||
@Test | ||
@DisplayName("Test that whispers are parsed by IRCMessageEvent") | ||
void parseWhisper() { | ||
IRCMessageEvent e = build("@badges=;color=;display-name=HexaFice;emotes=;message-id=103;thread-id=142621956_149223493;turbo=0;user-id=142621956;user-type= " + | ||
":hexafice!hexafice@hexafice.tmi.twitch.tv WHISPER twitch4j :test 123"); | ||
|
||
assertEquals("test 123", e.getMessage().orElse(null)); | ||
assertEquals("WHISPER", e.getCommandType()); | ||
assertEquals("142621956", e.getUserId()); | ||
assertEquals("hexafice", e.getUserName()); | ||
assertEquals("HexaFice", e.getTagValue("display-name").orElse(null)); | ||
assertEquals("twitch4j", e.getChannelName().orElse(null)); | ||
assertTrue(e.getBadges() == null || e.getBadges().isEmpty()); | ||
assertTrue(e.getBadgeInfo() == null || e.getBadgeInfo().isEmpty()); | ||
} | ||
|
||
private static IRCMessageEvent build(String raw) { | ||
return new IRCMessageEvent(raw, Collections.emptyMap(), Collections.emptyMap(), Collections.emptySet()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
common/src/test/java/com/github/twitch4j/common/util/TwitchUtilsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.github.twitch4j.common.util; | ||
|
||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Tag; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import static com.github.twitch4j.common.util.TwitchUtils.parseBadges; | ||
import static java.util.Collections.emptyMap; | ||
import static java.util.Collections.singletonMap; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
@Tag("unittest") | ||
class TwitchUtilsTest { | ||
|
||
@Test | ||
@DisplayName("Tests TwitchUtils.parseBadges") | ||
void badgesParseTest() { | ||
assertEquals(emptyMap(), parseBadges(null)); | ||
assertEquals(emptyMap(), parseBadges("")); | ||
assertEquals(emptyMap(), parseBadges(" ")); | ||
|
||
assertEquals(singletonMap("subscriber", "15"), parseBadges("subscriber/15")); | ||
assertEquals(singletonMap("subscriber", "15/3"), parseBadges("subscriber/15/3")); | ||
assertEquals(singletonMap("a b", "c d"), parseBadges("a\\sb/c\\sd")); | ||
|
||
assertEquals(mapOf("subscriber", "18", "no_audio", "1"), parseBadges("subscriber/18,no_audio/1")); | ||
assertEquals(mapOf("subscriber", "19", "no_audio", null), parseBadges("subscriber/19,no_audio/")); | ||
assertEquals(mapOf("follower", "20", "no_video", null), parseBadges("follower/20,no_video")); | ||
} | ||
|
||
private static <K, V> Map<K, V> mapOf(K key1, V value1, K key2, V value2) { | ||
Map<K, V> map = new HashMap<>(); | ||
map.put(key1, value1); | ||
map.put(key2, value2); | ||
return map; | ||
} | ||
|
||
} |