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