1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
pub mod api;
pub mod command;
pub mod commands;
pub mod spam;
// ----------------------------------------------------------------------------
#[cfg(test)]
mod test {
use super::{
api::{MockTwitchEventSubApi, TwitchApiWrapper},
command::{handle_command_if_applicable, CommandMap},
commands::{ping, ChatCommand},
spam::Spam,
};
use serde_json::json;
use twitcheventsub::MessageData;
/// Simulates a twitch chat message
fn create_chat_msg(cmd: &str, chatter_id: &str) -> serde_json::Value {
json!({
"broadcaster_user_id": "938429017",
"broadcaster_user_name": "mostlymaxi",
"broadcaster_user_login": "mostlymaxi",
"chatter_user_id": format!("{chatter_id}"),
"chatter_user_name": "mostlymaxi",
"chatter_user_login": "mostlymaxi",
"message_id": "3104f083-2bdb-4d6a-bb5d-30b407876ea4",
"message": {
"text": format!("{cmd}"),
"fragments": [
{
"type": "text",
"text": "!ping",
"cheermote": null,
"emote": null,
"mention": null
}
]
},
"color": "#FF0000",
"badges": [
{
"set_id": "broadcaster",
"id": "1",
"info": ""
},
{
"set_id": "subscriber",
"id": "0",
"info": "3"
}
],
"message_type": "text",
"cheer": null,
"reply": null,
"channel_points_custom_reward_id": null,
"channel_points_animation_id": null
})
}
/// Test handling of various command scenarios, including spam detection and invalid commands
#[test]
fn test_chat_command_handling() {
let mut commands = CommandMap::new();
commands.insert(ping::MostlyPing::new());
let mut api = TwitchApiWrapper::Test(MockTwitchEventSubApi::init_twitch_api());
let mut spam = Spam::default();
const BOT_ID: &str = "id_bot";
// Create a variety of test cases to cover different command scenarios
let chat_messages = vec![
// Basic valid command
create_chat_msg("!ping", "id_ping0"),
// Valid command with arguments
create_chat_msg("!ping with args", "id_ping1"),
// Non-existent command
create_chat_msg("!nonexistent", "id_phantom"),
// Message without the command prefix
create_chat_msg("ping", "id_invalid_no_prefix"),
// Valid command, but sent by the bot itself
create_chat_msg("!ping", BOT_ID),
// Empty command (just the prefix)
create_chat_msg("!", "id_empty_command"),
// Command with extra spaces
create_chat_msg("!ping ", "id_ping_extra_spaces"),
// Command with special characters
create_chat_msg("!ping$@", "id_ping_special_chars"),
// Mixed case command
create_chat_msg("!Ping", "id_mixed_case"),
// Spam check (with same user/chatter id)
create_chat_msg("!ping", "id_spam"),
create_chat_msg("!ping2", "id_spam"),
create_chat_msg("!ping$@", "id_spam"),
create_chat_msg("!Ping", "id_spam"),
];
for (_i, chat_msg) in chat_messages.into_iter().enumerate() {
// // Simulating time delay between commands
// if i > 0 {
// std::thread::sleep(Duration::from_secs(1));
// }
let chat_msg: MessageData = serde_json::from_value(chat_msg).unwrap();
handle_command_if_applicable(&chat_msg, &mut api, &mut commands, BOT_ID, &mut spam);
}
}
}