From 9545d37ab02d20be11820ff20b57bc98a1b6fb21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Wed, 11 Mar 2020 20:53:49 +0100 Subject: [PATCH] tests: add tests on IRC protocol functions and some callbacks Functions tested: * irc_protocol_is_numeric_command * irc_protocol_log_level_for_command * irc_protocol_tags * irc_protocol_nick_address * irc_protocol_cb_account * irc_protocol_cb_away * irc_protocol_cb_001 * irc_protocol_cb_005 --- ChangeLog.adoc | 1 + tests/scripts/test-scripts.cpp | 2 +- tests/tests.h | 2 + tests/unit/plugins/irc/test-irc-protocol.cpp | 427 +++++++++++++++++++ 4 files changed, 431 insertions(+), 1 deletion(-) diff --git a/ChangeLog.adoc b/ChangeLog.adoc index 10d65754a..51950e48e 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -48,6 +48,7 @@ Bug fixes:: Tests:: * scripts: fix generation of test scripts with Python 3.8 + * unit: add tests on IRC protocol functions and callbacks * unit: add tests on function secure_derive_key * unit: add tests on functions util_get_time_diff and util_file_get_content diff --git a/tests/scripts/test-scripts.cpp b/tests/scripts/test-scripts.cpp index 34ca7643f..1ece28301 100644 --- a/tests/scripts/test-scripts.cpp +++ b/tests/scripts/test-scripts.cpp @@ -36,7 +36,7 @@ extern "C" #include "src/plugins/plugin.h" } -extern void run_cmd (const char *command); +#include "tests/tests.h" struct t_hook *api_hook_print = NULL; int api_tests_ok = 0; diff --git a/tests/tests.h b/tests/tests.h index d11c33601..bc3f2533f 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -32,4 +32,6 @@ } \ free (str); +extern void run_cmd (const char *command); + #endif /* WEECHAT_TESTS_H */ diff --git a/tests/unit/plugins/irc/test-irc-protocol.cpp b/tests/unit/plugins/irc/test-irc-protocol.cpp index f26181991..644f97694 100644 --- a/tests/unit/plugins/irc/test-irc-protocol.cpp +++ b/tests/unit/plugins/irc/test-irc-protocol.cpp @@ -23,13 +23,137 @@ extern "C" { +#include "src/core/wee-config-file.h" +#include "src/core/wee-hashtable.h" +#include "src/gui/gui-color.h" #include "src/plugins/irc/irc-protocol.h" +#include "src/plugins/irc/irc-channel.h" +#include "src/plugins/irc/irc-config.h" +#include "src/plugins/irc/irc-nick.h" +#include "src/plugins/irc/irc-server.h" + +extern int irc_protocol_is_numeric_command (const char *str); +extern int irc_protocol_log_level_for_command (const char *command); +extern const char *irc_protocol_nick_address (struct t_irc_server *server, + int server_message, + struct t_irc_nick *nick, + const char *nickname, + const char *address); } +#include "tests/tests.h" + +#define IRC_FAKE_SERVER "fake" +#define IRC_MSG_005 "PREFIX=(ohv)@%+ MAXLIST=bqeI:100 MODES=4 " \ + "NETWORK=StaticBox STATUSMSG=@+ CALLERID=g " \ + "CASEMAPPING=strict-rfc1459 NICKLEN=30 MAXNICKLEN=31 " \ + "USERLEN=16 HOSTLEN=32 CHANNELLEN=50 TOPICLEN=390 DEAF=D " \ + "CHANTYPES=# CHANMODES=eIbq,k,flj,CFLMPQScgimnprstuz " \ + "MONITOR=100" + +struct t_irc_server *ptr_server; + TEST_GROUP(IrcProtocol) { }; +/* + * Tests functions: + * irc_protocol_is_numeric_command + */ + +TEST(IrcProtocol, IsNumericCommand) +{ + LONGS_EQUAL(0, irc_protocol_is_numeric_command (NULL)); + LONGS_EQUAL(0, irc_protocol_is_numeric_command ("")); + LONGS_EQUAL(0, irc_protocol_is_numeric_command ("abc")); + + LONGS_EQUAL(1, irc_protocol_is_numeric_command ("0")); + LONGS_EQUAL(1, irc_protocol_is_numeric_command ("1")); + LONGS_EQUAL(1, irc_protocol_is_numeric_command ("12")); + LONGS_EQUAL(1, irc_protocol_is_numeric_command ("123")); +} + +/* + * Tests functions: + * irc_protocol_log_level_for_command + */ + +TEST(IrcProtocol, LogLevelForCommand) +{ + LONGS_EQUAL(0, irc_protocol_log_level_for_command (NULL)); + LONGS_EQUAL(0, irc_protocol_log_level_for_command ("")); + + LONGS_EQUAL(1, irc_protocol_log_level_for_command ("privmsg")); + LONGS_EQUAL(1, irc_protocol_log_level_for_command ("notice")); + + LONGS_EQUAL(2, irc_protocol_log_level_for_command ("nick")); + + LONGS_EQUAL(4, irc_protocol_log_level_for_command ("join")); + LONGS_EQUAL(4, irc_protocol_log_level_for_command ("part")); + LONGS_EQUAL(4, irc_protocol_log_level_for_command ("quit")); + LONGS_EQUAL(4, irc_protocol_log_level_for_command ("nick_back")); + + LONGS_EQUAL(3, irc_protocol_log_level_for_command ("001")); + LONGS_EQUAL(3, irc_protocol_log_level_for_command ("away")); + LONGS_EQUAL(3, irc_protocol_log_level_for_command ("kick")); + LONGS_EQUAL(3, irc_protocol_log_level_for_command ("topic")); +} + +/* + * Tests functions: + * irc_protocol_tags + */ + +TEST(IrcProtocol, Tags) +{ + POINTERS_EQUAL(NULL, irc_protocol_tags (NULL, NULL, NULL, NULL)); + + /* command */ + STRCMP_EQUAL("irc_privmsg,log1", + irc_protocol_tags ("privmsg", NULL, NULL, NULL)); + STRCMP_EQUAL("irc_join,log4", + irc_protocol_tags ("join", NULL, NULL, NULL)); + + /* command and empty tags */ + STRCMP_EQUAL("irc_privmsg,log1", + irc_protocol_tags ("privmsg", "", NULL, NULL)); + STRCMP_EQUAL("irc_join,log4", + irc_protocol_tags ("join", "", NULL, NULL)); + + /* command and tags */ + STRCMP_EQUAL("irc_privmsg,tag1,tag2,log1", + irc_protocol_tags ("privmsg", "tag1,tag2", NULL, NULL)); + STRCMP_EQUAL("irc_join,tag1,tag2,log4", + irc_protocol_tags ("join", "tag1,tag2", NULL, NULL)); + + /* command, tags and empty nick */ + STRCMP_EQUAL("irc_privmsg,tag1,tag2,log1", + irc_protocol_tags ("privmsg", "tag1,tag2", "", NULL)); + STRCMP_EQUAL("irc_join,tag1,tag2,log4", + irc_protocol_tags ("join", "tag1,tag2", "", NULL)); + + /* command, tags and nick */ + STRCMP_EQUAL("irc_privmsg,tag1,tag2,nick_alice,log1", + irc_protocol_tags ("privmsg", "tag1,tag2", "alice", NULL)); + STRCMP_EQUAL("irc_join,tag1,tag2,nick_bob,log4", + irc_protocol_tags ("join", "tag1,tag2", "bob", NULL)); + + /* command, tags, nick and empty address */ + STRCMP_EQUAL("irc_privmsg,tag1,tag2,nick_alice,log1", + irc_protocol_tags ("privmsg", "tag1,tag2", "alice", "")); + STRCMP_EQUAL("irc_join,tag1,tag2,nick_bob,log4", + irc_protocol_tags ("join", "tag1,tag2", "bob", "")); + + /* command, tags, nick and address */ + STRCMP_EQUAL("irc_privmsg,tag1,tag2,nick_alice,host_example.com,log1", + irc_protocol_tags ("privmsg", "tag1,tag2", "alice", + "example.com")); + STRCMP_EQUAL("irc_join,tag1,tag2,nick_bob,host_example.com,log4", + irc_protocol_tags ("join", "tag1,tag2", "bob", + "example.com")); +} + /* * Tests functions: * irc_protocol_parse_time @@ -57,3 +181,306 @@ TEST(IrcProtocol, ParseTime) LONGS_EQUAL(1547386699, irc_protocol_parse_time ("1547386699.123")); LONGS_EQUAL(1547386699, irc_protocol_parse_time ("1547386699")); } + +TEST_GROUP(IrcProtocolWithServer) +{ + void run_cmd_server (const char *command) + { + char str_command[4096]; + + snprintf (str_command, sizeof (str_command), + "/command -buffer irc.server." IRC_FAKE_SERVER " irc %s", + command); + run_cmd (str_command); + } + + void setup () + { + printf ("\n"); + + /* create a fake server (no I/O) */ + run_cmd ("/server add " IRC_FAKE_SERVER " fake:127.0.0.1 " + "-nicks=nick1,nick2,nick3"); + + /* connect to the fake server */ + run_cmd ("/connect " IRC_FAKE_SERVER); + + /* get the server pointer */ + ptr_server = irc_server_search (IRC_FAKE_SERVER); + } + + void teardown () + { + /* disconnect and delete the fake server */ + run_cmd ("/disconnect " IRC_FAKE_SERVER); + run_cmd ("/server del " IRC_FAKE_SERVER); + ptr_server = NULL; + } +}; + +/* + * Tests functions: + * irc_protocol_nick_address + */ + +TEST(IrcProtocolWithServer, NickAddress) +{ + struct t_irc_nick *ptr_nick; + char result[1024]; + + run_cmd_server ("/server fakerecv :server 001 alice"); + run_cmd ("/command -buffer irc.server." IRC_FAKE_SERVER " irc " + "/server fakerecv :alice!user@host JOIN #test"); + + ptr_nick = ptr_server->channels->nicks; + + STRCMP_EQUAL("", irc_protocol_nick_address (NULL, 0, NULL, + NULL, NULL)); + STRCMP_EQUAL("", irc_protocol_nick_address (ptr_server, 0, NULL, + NULL, NULL)); + STRCMP_EQUAL("", irc_protocol_nick_address (ptr_server, 0, ptr_nick, + NULL, NULL)); + STRCMP_EQUAL("", irc_protocol_nick_address (ptr_server, 0, ptr_nick, + NULL, NULL)); + + snprintf (result, sizeof (result), + "%s%s%s", + ptr_nick->color, + "alice", + gui_color_get_custom ("reset")); + STRCMP_EQUAL(result, irc_protocol_nick_address (ptr_server, 0, ptr_nick, + "alice", NULL)); + + snprintf (result, sizeof (result), + "%s%s %s(%s%s%s)%s", + ptr_nick->color, + "alice", + gui_color_search_config ("chat_delimiters"), + gui_color_search_config ("chat_host"), + "example.com", + gui_color_search_config ("chat_delimiters"), + gui_color_get_custom ("reset")); + STRCMP_EQUAL(result, irc_protocol_nick_address (ptr_server, 0, ptr_nick, + "alice", "example.com")); + + config_file_option_set (irc_config_look_color_nicks_in_server_messages, + "off", 1); + snprintf (result, sizeof (result), + "%s%s %s(%s%s%s)%s", + ptr_nick->color, + "alice", + gui_color_search_config ("chat_delimiters"), + gui_color_search_config ("chat_host"), + "example.com", + gui_color_search_config ("chat_delimiters"), + gui_color_get_custom ("reset")); + STRCMP_EQUAL(result, irc_protocol_nick_address (ptr_server, 0, ptr_nick, + "alice", "example.com")); + snprintf (result, sizeof (result), + "%s%s %s(%s%s%s)%s", + gui_color_search_config ("chat_nick"), + "alice", + gui_color_search_config ("chat_delimiters"), + gui_color_search_config ("chat_host"), + "example.com", + gui_color_search_config ("chat_delimiters"), + gui_color_get_custom ("reset")); + STRCMP_EQUAL(result, irc_protocol_nick_address (ptr_server, 1, ptr_nick, + "alice", "example.com")); + config_file_option_reset (irc_config_look_color_nicks_in_server_messages, 0); +} + +/* + * Tests functions: + * irc_protocol_cb_account (without account-notify capability) + */ + +TEST(IrcProtocolWithServer, account_without_account_notify_cap) +{ + struct t_irc_nick *ptr_nick; + + run_cmd_server ("/server fakerecv :server 001 alice"); + run_cmd ("/command -buffer irc.server." IRC_FAKE_SERVER " irc " + "/server fakerecv :alice!user@host JOIN #test"); + + ptr_nick = ptr_server->channels->nicks; + + POINTERS_EQUAL(NULL, ptr_nick->account); + + run_cmd_server ("/server fakerecv :alice!user@host ACCOUNT *"); + POINTERS_EQUAL(NULL, ptr_nick->account); + + run_cmd_server ("/server fakerecv :alice!user@host ACCOUNT new_account"); + POINTERS_EQUAL(NULL, ptr_nick->account); +} + +/* + * Tests functions: + * irc_protocol_cb_account (with account-notify capability) + */ + +TEST(IrcProtocolWithServer, account_with_account_notify_cap) +{ + struct t_irc_nick *ptr_nick; + + /* assume "account-notify" capability is enabled in server */ + hashtable_set (ptr_server->cap_list, "account-notify", NULL); + + run_cmd_server ("/server fakerecv :server 001 alice"); + run_cmd ("/command -buffer irc.server." IRC_FAKE_SERVER " irc " + "/server fakerecv :alice!user@host JOIN #test"); + + ptr_nick = ptr_server->channels->nicks; + + POINTERS_EQUAL(NULL, ptr_nick->account); + + run_cmd_server ("/server fakerecv :alice!user@host ACCOUNT new_account"); + STRCMP_EQUAL("new_account", ptr_nick->account); + + run_cmd_server ("/server fakerecv :alice!user@host ACCOUNT new_account2"); + STRCMP_EQUAL("new_account2", ptr_nick->account); + + run_cmd_server ("/server fakerecv :alice!user@host ACCOUNT *"); + POINTERS_EQUAL(NULL, ptr_nick->account); +} + +/* + * Tests functions: + * irc_protocol_cb_away + */ + +TEST(IrcProtocolWithServer, away) +{ + struct t_irc_nick *ptr_nick; + + run_cmd_server ("/server fakerecv :server 001 alice"); + run_cmd ("/command -buffer irc.server." IRC_FAKE_SERVER " irc " + "/server fakerecv :alice!user@host JOIN #test"); + + ptr_nick = ptr_server->channels->nicks; + + LONGS_EQUAL(0, ptr_nick->away); + + run_cmd_server ("/server fakerecv :alice!user@host AWAY :Holidays!"); + + LONGS_EQUAL(1, ptr_nick->away); +} + +/* + * Tests functions: + * irc_protocol_cb_001 (empty) + */ + +TEST(IrcProtocolWithServer, 001_empty) +{ + LONGS_EQUAL(0, ptr_server->is_connected); + STRCMP_EQUAL("nick1", ptr_server->nick); + + run_cmd_server ("/server fakerecv :server 001 alice"); + + LONGS_EQUAL(1, ptr_server->is_connected); + STRCMP_EQUAL("alice", ptr_server->nick); +} + +/* + * Tests functions: + * irc_protocol_cb_001 (welcome) + */ + +TEST(IrcProtocolWithServer, 001_welcome) +{ + run_cmd ("/set irc.server." IRC_FAKE_SERVER ".autojoin \"#autojoin1\""); + run_cmd ("/set irc.server." IRC_FAKE_SERVER ".command " + "\"/join #test1;/join #test2;/query remote_nick\""); + LONGS_EQUAL(0, ptr_server->is_connected); + STRCMP_EQUAL("nick1", ptr_server->nick); + + run_cmd_server ("/server fakerecv :server 001 alice " + ":Welcome on this server!"); + + LONGS_EQUAL(1, ptr_server->is_connected); + STRCMP_EQUAL("alice", ptr_server->nick); + CHECK(ptr_server->channels); + STRCMP_EQUAL("remote_nick", ptr_server->channels->name); +} + +/* + * Tests functions: + * irc_protocol_cb_005 (empty) + */ + +TEST(IrcProtocolWithServer, 005_empty) +{ + run_cmd_server ("/server fakerecv :server 001 alice"); + + POINTERS_EQUAL(NULL, ptr_server->prefix_modes); + POINTERS_EQUAL(NULL, ptr_server->prefix_chars); + + run_cmd_server ("/server fakerecv :server 005 alice TEST=A"); + + POINTERS_EQUAL(NULL, ptr_server->prefix_modes); + POINTERS_EQUAL(NULL, ptr_server->prefix_chars); +} + +/* + * Tests functions: + * irc_protocol_cb_005 (full) + */ + +TEST(IrcProtocolWithServer, 005_full) +{ + run_cmd_server ("/server fakerecv :server 001 alice"); + + POINTERS_EQUAL(NULL, ptr_server->prefix_modes); + POINTERS_EQUAL(NULL, ptr_server->prefix_chars); + LONGS_EQUAL(0, ptr_server->nick_max_length); + LONGS_EQUAL(0, ptr_server->user_max_length); + LONGS_EQUAL(0, ptr_server->host_max_length); + LONGS_EQUAL(0, ptr_server->casemapping); + POINTERS_EQUAL(NULL, ptr_server->chantypes); + POINTERS_EQUAL(NULL, ptr_server->chanmodes); + LONGS_EQUAL(0, ptr_server->monitor); + POINTERS_EQUAL(NULL, ptr_server->isupport); + + run_cmd_server ("/server fakerecv :server 005 alice " IRC_MSG_005 " " + ":are supported by this server"); + + STRCMP_EQUAL("ohv", ptr_server->prefix_modes); + STRCMP_EQUAL("@%+", ptr_server->prefix_chars); + LONGS_EQUAL(30, ptr_server->nick_max_length); + LONGS_EQUAL(16, ptr_server->user_max_length); + LONGS_EQUAL(32, ptr_server->host_max_length); + LONGS_EQUAL(1, ptr_server->casemapping); + STRCMP_EQUAL("#", ptr_server->chantypes); + STRCMP_EQUAL("eIbq,k,flj,CFLMPQScgimnprstuz", ptr_server->chanmodes); + LONGS_EQUAL(100, ptr_server->monitor); + CHECK(ptr_server->isupport[0] == ' '); + STRCMP_EQUAL(IRC_MSG_005, ptr_server->isupport + 1); +} + +/* + * Tests functions: + * irc_protocol_cb_005 (multiple messages) + */ + +TEST(IrcProtocolWithServer, 005_multiple_messages) +{ + run_cmd_server ("/server fakerecv :server 001 alice"); + + POINTERS_EQUAL(NULL, ptr_server->prefix_modes); + POINTERS_EQUAL(NULL, ptr_server->prefix_chars); + LONGS_EQUAL(0, ptr_server->host_max_length); + POINTERS_EQUAL(NULL, ptr_server->isupport); + + run_cmd_server ("/server fakerecv :server 005 alice " + "PREFIX=(ohv)@%+ " + ":are supported by this server"); + run_cmd_server ("/server fakerecv :server 005 alice " + "HOSTLEN=24 " + ":are supported by this server"); + + STRCMP_EQUAL("ohv", ptr_server->prefix_modes); + STRCMP_EQUAL("@%+", ptr_server->prefix_chars); + LONGS_EQUAL(24, ptr_server->host_max_length); + STRCMP_EQUAL(" PREFIX=(ohv)@%+ HOSTLEN=24", ptr_server->isupport); +}