1 /*
2 ircdtorture: an IRC RFC compliancy tester
3 (c) 2005 Jelmer Vernooij <jelmer@nl.linux.org>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <check.h>
23 #include "ctrlproxy.h"
24
25 gboolean network_nick_set_nick(struct network_nick *, const char *);
26 gboolean network_nick_set_hostmask(struct network_nick *, const char *);
27 struct network_nick *find_add_network_nick(struct irc_network_state *n, const char *name);
28
29 START_TEST(state_modes_set_mode)
30 irc_modes_t in;
31 modes_clear(in);
32 fail_unless (modes_set_mode(in, '@'));
33 fail_unless (in[(unsigned char)'@'] == TRUE);
34 fail_unless (modes_set_mode(in, '%'));
35 fail_unless (in[(unsigned char)'%'] == TRUE);
36 END_TEST
37
38 START_TEST(state_prefixes_remove_prefix)
39 irc_modes_t in;
40 memset(in, 0, sizeof(in));
41 fail_if (modes_unset_mode(in, '@'));
42 in[(unsigned char)'%'] = TRUE;
43 fail_unless (modes_unset_mode(in, '%'));
44 fail_unless (in[(unsigned char)'%'] == FALSE);
45 fail_if (modes_unset_mode(in, '%'));
46 END_TEST
47
48 START_TEST(state_init)
49 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
50
51 fail_if(ns == NULL, "network_state_init returned NULL");
52
53 fail_unless (strcmp(ns->me.nick, "bla") == 0);
54 fail_unless (strcmp(ns->me.username, "Gebruikersnaam") == 0);
55 fail_unless (strcmp(ns->me.hostname, "Computernaam") == 0);
56
57 fail_unless (g_list_length(ns->channels) == 0);
58 END_TEST
59
state_process(struct irc_network_state * ns,const char * line)60 void state_process(struct irc_network_state *ns, const char *line)
61 {
62 struct irc_line *l;
63 l = irc_parse_line(line);
64 g_assert(l);
65 g_assert(state_handle_data(ns, l));
66 free_line(l);
67 }
68
69 START_TEST(state_join_me)
70 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
71 struct irc_channel_state *cs;
72
73 fail_if (!ns);
74
75 state_process(ns, ":bla!user@host JOIN #examplechannel");
76
77 fail_unless (g_list_length(ns->channels) == 1);
78
79 cs = ns->channels->data;
80
81 fail_unless (strcmp(cs->name, "#examplechannel") == 0);
82 END_TEST
83
84 START_TEST(state_join_other)
85 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
86 struct irc_channel_state *cs;
87
88 fail_if (!ns);
89
90 state_process(ns, ":bla!user@host JOIN #examplechannel");
91 state_process(ns, ":foo!userx@host JOIN #examplechannel");
92
93 fail_unless (g_list_length(ns->channels) == 1);
94
95 cs = ns->channels->data;
96 fail_unless (g_list_length(cs->nicks) == 2);
97 END_TEST
98
99
100 START_TEST(state_topic)
101 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
102 struct irc_channel_state *cs;
103
104 fail_if (!ns);
105
106 state_process(ns, ":bla!user@host JOIN #examplechannel");
107 state_process(ns, ":bla!user@host TOPIC #examplechannel :This is the topic");
108
109 cs = ns->channels->data;
110
111 fail_unless (strcmp(cs->topic, "This is the topic") == 0);
112 fail_unless (abs(cs->topic_set_time - time(NULL)) < 5);
113 fail_unless (strcmp(cs->topic_set_by, "bla") == 0);
114 END_TEST
115
116
117 START_TEST(state_part)
118 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
119 struct irc_channel_state *cs;
120
121 fail_if (!ns);
122
123 state_process(ns, ":bla!user@host JOIN #examplechannel");
124
125 fail_unless (g_list_length(ns->channels) == 1);
126
127 cs = ns->channels->data;
128
129 fail_unless (strcmp(cs->name, "#examplechannel") == 0);
130
131 state_process(ns, ":bla!user@host PART #examplechannel");
132
133 fail_unless (g_list_length(ns->channels) == 0);
134 END_TEST
135
136 START_TEST(state_cycle)
137 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
138 struct irc_channel_state *cs;
139
140 fail_if (!ns);
141
142 state_process(ns, ":bla!user@host JOIN #examplechannel");
143
144 fail_unless (g_list_length(ns->channels) == 1);
145
146 cs = ns->channels->data;
147
148 fail_unless (strcmp(cs->name, "#examplechannel") == 0);
149
150 state_process(ns, ":bla!user@host PART #examplechannel");
151
152 fail_unless (g_list_length(ns->channels) == 0);
153
154 state_process(ns, ":bla!user@host JOIN #examplechannel");
155
156 fail_unless (g_list_length(ns->channels) == 1);
157 END_TEST
158
159 START_TEST(state_kick)
160 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
161 struct irc_channel_state *cs;
162
163 fail_if (!ns);
164
165 state_process(ns, ":bla!user@host JOIN #examplechannel");
166
167 fail_unless (g_list_length(ns->channels) == 1);
168
169 cs = ns->channels->data;
170
171 fail_unless (strcmp(cs->name, "#examplechannel") == 0);
172
173 state_process(ns, ":bloe!anotheruser@host KICK #examplechannel bla :Doei");
174
175 fail_unless (g_list_length(ns->channels) == 0);
176 END_TEST
177
178 START_TEST(state_nick_change_my)
179 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
180
181 fail_if(ns == NULL);
182
183 state_process(ns, ":bla!user@host NICK blie");
184
185 fail_unless(strcmp(ns->me.nick, "blie") == 0);
186 END_TEST
187
188 START_TEST(state_nick_change_other)
189 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
190
191 fail_if(ns == NULL);
192
193 state_process(ns, ":foo!user@bar PRIVMSG bla :Hi");
194
195 state_process(ns, ":foo!user@bar NICK blie");
196
197 fail_if (find_network_nick(ns, "foo") != NULL);
198 fail_if (find_network_nick(ns, "blie") == NULL);
199 END_TEST
200
201 START_TEST(state_set_nick)
202 struct network_nick nn;
203 memset(&nn, 0, sizeof(nn));
204
205 fail_if (!network_nick_set_nick(&nn, "mynick"));
206 fail_unless (strcmp(nn.nick, "mynick") == 0);
207 fail_unless (strcmp(nn.hostmask, "mynick!(null)@(null)") == 0);
208 fail_if (!network_nick_set_nick(&nn, "mynick"));
209 fail_unless (strcmp(nn.nick, "mynick") == 0);
210 fail_unless (strcmp(nn.hostmask, "mynick!(null)@(null)") == 0);
211 fail_if (network_nick_set_nick(NULL, NULL));
212 END_TEST
213
214 START_TEST(state_set_hostmask)
215 struct network_nick nn;
216 memset(&nn, 0, sizeof(nn));
217
218 fail_if (!network_nick_set_hostmask(&nn, "ikke!~uname@uhost"));
219 fail_if (!nn.nick || strcmp(nn.nick, "ikke") != 0);
220 fail_if (!nn.username || strcmp(nn.username, "~uname") != 0);
221 fail_if (!nn.hostname || strcmp(nn.hostname, "uhost") != 0);
222 fail_if (!network_nick_set_hostmask(&nn, "ikke!~uname@uhost"));
223 fail_if (network_nick_set_hostmask(NULL, NULL));
224 fail_if (network_nick_set_hostmask(&nn, NULL));
225
226 fail_if (network_nick_set_hostmask(&nn, "ikkeongeldig"));
227 fail_if (network_nick_set_hostmask(&nn, "ikke!ongeldig"));
228 END_TEST
229
230 START_TEST(state_find_network_nick)
231 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
232
233 fail_if(ns == NULL);
234
235 state_process(ns, ":foo!user@host PRIVMSG bla :Hoi");
236
237 fail_unless(find_network_nick(ns, "foo") != NULL);
238 fail_unless(find_network_nick(ns, "foobla") == NULL);
239 END_TEST
240
241 START_TEST(state_find_add_network_nick)
242 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
243
244 fail_if(ns == NULL);
245
246 fail_if (find_add_network_nick(ns, "foo") == NULL);
247 fail_if (find_add_network_nick(ns, "foo") == NULL);
248 END_TEST
249
250 START_TEST(state_handle_state_data)
251 struct irc_network_state *ns = network_state_init("bla", "Gebruikersnaam", "Computernaam");
252 struct irc_line l;
253 char *args1[] = {"JOIN", "#bla", NULL};
254 char *args2[] = {"UNKNOWN", "#bla", NULL};
255
256 memset(&l, 0, sizeof(l));
257 l.origin = "foo";
258
259 fail_if(ns == NULL);
260
261 fail_unless (state_handle_data(ns, NULL) == FALSE);
262 fail_unless (state_handle_data(ns, &l) == FALSE);
263 l.argc = 2;
264 l.args = args1;
265 fail_unless (state_handle_data(ns, &l) == TRUE);
266 l.argc = 2;
267 l.args = args2;
268 fail_unless (state_handle_data(ns, &l) == FALSE);
269 END_TEST
270
271 START_TEST(test_string2mode)
272 irc_modes_t modes;
273 modes_clear(modes);
274 string2mode("+", modes);
275 string2mode("+o-o", modes);
276 fail_unless(modes['o'] == FALSE);
277 string2mode("+o", modes);
278 fail_unless(modes['o'] == TRUE);
279 string2mode("+oa", modes);
280 fail_unless(modes['a'] == TRUE);
281 fail_unless(modes['o'] == TRUE);
282 string2mode("+o-a", modes);
283 fail_unless(modes['a'] == FALSE);
284 fail_unless(modes['o'] == TRUE);
285 END_TEST
286
287 START_TEST(test_nicklist)
288 GList *mylist = NULL;
289
290 fail_unless(nicklist_add_entry(&mylist, "user@host", "op@otherhost", 0));
291 fail_unless(nicklist_add_entry(&mylist, "anotheruser@host", NULL, 0));
292 fail_unless(g_list_length(mylist) == 2);
293 fail_unless(find_nicklist_entry(mylist, "user@host") != NULL);
294 fail_unless(find_nicklist_entry(mylist, "anonymous@host") == NULL);
295 fail_unless(nicklist_remove_entry(&mylist, "user@host"));
296 fail_unless(g_list_length(mylist) == 1);
297 fail_unless(!nicklist_remove_entry(&mylist, "anonymous@host"));
298 free_nicklist(&mylist);
299 fail_unless(mylist == NULL);
300 END_TEST
301
302 START_TEST(test_mode2string)
303 char *ret;
304 irc_modes_t modes;
305 modes_clear(modes);
306 fail_unless(mode2string(modes) == NULL);
307 modes['o'] = TRUE;
308 ret = mode2string(modes);
309 fail_unless(strcmp(ret, "+o") == 0);
310 modes['k'] = TRUE;
311 ret = mode2string(modes);
312 fail_unless(strcmp(ret, "+ko") == 0);
313 END_TEST
314
state_suite(void)315 Suite *state_suite(void)
316 {
317 Suite *s = suite_create("state");
318 TCase *tc_core = tcase_create("Core");
319 suite_add_tcase(s, tc_core);
320 tcase_add_test(tc_core, state_init);
321 tcase_add_test(tc_core, state_join_me);
322 tcase_add_test(tc_core, state_join_other);
323 tcase_add_test(tc_core, state_topic);
324 tcase_add_test(tc_core, state_part);
325 tcase_add_test(tc_core, state_cycle);
326 tcase_add_test(tc_core, state_kick);
327 tcase_add_test(tc_core, state_set_nick);
328 tcase_add_test(tc_core, state_set_nick);
329 tcase_add_test(tc_core, state_set_hostmask);
330 tcase_add_test(tc_core, state_nick_change_my);
331 tcase_add_test(tc_core, state_nick_change_other);
332 tcase_add_test(tc_core, state_find_network_nick);
333 tcase_add_test(tc_core, state_find_add_network_nick);
334 tcase_add_test(tc_core, state_handle_state_data);
335 tcase_add_test(tc_core, state_modes_set_mode);
336 tcase_add_test(tc_core, state_prefixes_remove_prefix);
337 tcase_add_test(tc_core, test_mode2string);
338 tcase_add_test(tc_core, test_string2mode);
339 tcase_add_test(tc_core, test_nicklist);
340 return s;
341 }
342