1 /*
2 * Copyright (C) 2008-2020 The Communi Project
3 *
4 * This test is free, and not covered by the BSD license. There is no
5 * restriction applied to their modification, redistribution, using and so on.
6 * You can study them, modify them, use them in your own program - either
7 * completely or partially.
8 */
9
10 #include "ircmessage.h"
11 #include "ircconnection.h"
12 #include "ircprotocol.h"
13 #include <QtTest/QtTest>
14 #include <QTextCodec>
15 #include <QtCore/QScopedPointer>
16
17 #ifdef Q_OS_LINUX
18 #include "ircmessagedecoder_p.h"
19 #endif // Q_OS_LINUX
20
21 class tst_IrcMessage : public QObject
22 {
23 Q_OBJECT
24
25 private slots:
26 void testDefaults();
27
28 void testToData();
29
30 void testPrefix_data();
31 void testPrefix();
32
33 void testParameters_data();
34 void testParameters();
35
36 void testFlags();
37
38 void testEncoding_data();
39 void testEncoding();
40
41 void testDecoder_data();
42 void testDecoder();
43
44 void testTags();
45 void testServerTime();
46
47 void testAccount_data();
48 void testAccount();
49
50 void testAccountMessage_data();
51 void testAccountMessage();
52 void testAwayMessage_data();
53 void testAwayMessage();
54 void testCapabilityMessage_data();
55 void testCapabilityMessage();
56 void testErrorMessage_data();
57 void testErrorMessage();
58 void testHostChangeMessage_data();
59 void testHostChangeMessage();
60 void testInviteMessage_data();
61 void testInviteMessage();
62 void testJoinMessage_data();
63 void testJoinMessage();
64 void testKickMessage_data();
65 void testKickMessage();
66 void testNamesMessage();
67 void testNickMessage_data();
68 void testNickMessage();
69 void testNoticeMessage_data();
70 void testNoticeMessage();
71 void testNumericMessage_data();
72 void testNumericMessage();
73 void testModeMessage_data();
74 void testModeMessage();
75 void testMotdMessage();
76 void testPartMessage_data();
77 void testPartMessage();
78 void testPingMessage();
79 void testPongMessage();
80 void testPrivateMessage_data();
81 void testPrivateMessage();
82 void testQuitMessage_data();
83 void testQuitMessage();
84 void testTopicMessage_data();
85 void testTopicMessage();
86 void testWhoReplyMessage_data();
87 void testWhoReplyMessage();
88
89 void testClone();
90 void testNullConnection();
91
92 void testDebug();
93 };
94
testDefaults()95 void tst_IrcMessage::testDefaults()
96 {
97 IrcMessage msg(nullptr);
98 QVERIFY(!msg.isValid());
99 QVERIFY(!msg.connection());
100 QCOMPARE(msg.type(), IrcMessage::Unknown);
101 QCOMPARE(msg.flags(), IrcMessage::None);
102 QCOMPARE(msg.encoding(), QByteArray("ISO-8859-15"));
103 QVERIFY(msg.prefix().isNull());
104 QVERIFY(msg.nick().isNull());
105 QVERIFY(msg.ident().isNull());
106 QVERIFY(msg.host().isNull());
107 QVERIFY(msg.command().isNull());
108 QVERIFY(msg.parameters().isEmpty());
109 QVERIFY(msg.toData().isEmpty());
110 }
111
testToData()112 void tst_IrcMessage::testToData()
113 {
114 IrcConnection connection;
115 IrcMessage* msg = IrcMessage::fromData(":nick!ident@host PRIVMSG user :hello there", &connection);
116 QCOMPARE(msg->toData(), QByteArray(":nick!ident@host PRIVMSG user :hello there"));
117
118 msg = IrcMessage::fromData(":nick!ident@host PRIVMSG user ::)", &connection);
119 QCOMPARE(msg->toData(), QByteArray(":nick!ident@host PRIVMSG user ::)"));
120
121 msg = IrcMessage::fromData(":nick!ident@host TOPIC #channel :", &connection);
122 QCOMPARE(msg->toData(), QByteArray(":nick!ident@host TOPIC #channel :"));
123
124 msg = IrcMessage::fromParameters("nick!ident@host", "PRIVMSG", QStringList() << "user" << "hello there", &connection);
125 QCOMPARE(msg->toData(), QByteArray(":nick!ident@host PRIVMSG user :hello there"));
126
127 msg = IrcMessage::fromParameters("nick!ident@host", "PRIVMSG", QStringList() << "user" << ":)", &connection);
128 QCOMPARE(msg->toData(), QByteArray(":nick!ident@host PRIVMSG user ::)"));
129
130 msg = IrcMessage::fromParameters("nick!ident@host", "TOPIC", QStringList() << "#channel" << "", &connection);
131 QCOMPARE(msg->toData(), QByteArray(":nick!ident@host TOPIC #channel :"));
132 }
133
testPrefix_data()134 void tst_IrcMessage::testPrefix_data()
135 {
136 QTest::addColumn<QString>("prefix");
137 QTest::addColumn<QString>("expected");
138 QTest::addColumn<QString>("nick");
139 QTest::addColumn<QString>("ident");
140 QTest::addColumn<QString>("host");
141
142 QTest::newRow("null") << QString() << QString() << QString() << QString() << QString();
143 QTest::newRow("empty") << QString("") << QString("") << QString() << QString() << QString();
144 QTest::newRow("space") << QString(" ") << QString(" ") << QString() << QString() << QString();
145 QTest::newRow("nick!ident@host") << QString("nick!ident@host") << QString("nick!ident@host") << QString("nick") << QString("ident") << QString("host");
146 }
147
testPrefix()148 void tst_IrcMessage::testPrefix()
149 {
150 QFETCH(QString, prefix);
151 QFETCH(QString, expected);
152 QFETCH(QString, nick);
153 QFETCH(QString, ident);
154 QFETCH(QString, host);
155
156 IrcMessage msg(nullptr);
157 msg.setPrefix(prefix);
158 QCOMPARE(msg.prefix(), expected);
159 QCOMPARE(msg.nick(), nick);
160 QCOMPARE(msg.ident(), ident);
161 QCOMPARE(msg.host(), host);
162 }
163
testParameters_data()164 void tst_IrcMessage::testParameters_data()
165 {
166 Irc::registerMetaTypes();
167
168 QTest::addColumn<QString>("prefix");
169 QTest::addColumn<QString>("command");
170 QTest::addColumn<QStringList>("params");
171 QTest::addColumn<IrcMessage::Type>("type");
172
173 QTest::newRow("null") << QString() << QString() << QStringList() << IrcMessage::Unknown;
174 QTest::newRow("message") << QString("nick!ident@host") << QString("PRIVMSG") << QStringList("p") << IrcMessage::Private;
175 QTest::newRow("notice") << QString("nick!ident@host") << QString("NOTICE") << QStringList("p") << IrcMessage::Notice;
176 }
177
testParameters()178 void tst_IrcMessage::testParameters()
179 {
180 QFETCH(QString, prefix);
181 QFETCH(QString, command);
182 QFETCH(QStringList, params);
183 QFETCH(IrcMessage::Type, type);
184
185 IrcConnection connection;
186 QScopedPointer<IrcMessage> message(IrcMessage::fromParameters(prefix, command, params, &connection));
187 QCOMPARE(message->type(), type);
188 QCOMPARE(message->prefix(), prefix);
189 QCOMPARE(message->command(), command);
190 QCOMPARE(message->parameters(), params);
191
192 for (int i = 0; i < params.count(); ++i)
193 QCOMPARE(message->parameter(i), params.at(i));
194
195 message->setParameter(5, "foo");
196 QCOMPARE(message->parameter(4), QString());
197 QCOMPARE(message->parameter(5), QString("foo"));
198 }
199
testFlags()200 void tst_IrcMessage::testFlags()
201 {
202 IrcMessage msg(nullptr);
203 msg.setPrefix("a!b@c");
204 QCOMPARE(msg.flags(), IrcMessage::None);
205
206 QVERIFY(!msg.testFlag(IrcMessage::Playback));
207 msg.setFlag(IrcMessage::Playback);
208 QVERIFY(msg.testFlag(IrcMessage::Playback));
209 QCOMPARE(msg.flags(), IrcMessage::Playback);
210
211 QVERIFY(!msg.testFlag(IrcMessage::Implicit));
212 msg.setFlag(IrcMessage::Implicit);
213 QVERIFY(msg.testFlag(IrcMessage::Implicit));
214 QCOMPARE(msg.flags(), IrcMessage::Playback | IrcMessage::Implicit);
215
216 msg.setFlag(IrcMessage::Playback, false);
217 QVERIFY(!msg.testFlag(IrcMessage::Playback));
218 QCOMPARE(msg.flags(), IrcMessage::Implicit);
219
220 msg.setFlags(IrcMessage::None);
221 QVERIFY(!msg.testFlag(IrcMessage::Implicit));
222 QVERIFY(!msg.testFlag(IrcMessage::Playback));
223 QCOMPARE(msg.flags(), IrcMessage::None);
224 }
225
testEncoding_data()226 void tst_IrcMessage::testEncoding_data()
227 {
228 QTest::addColumn<QByteArray>("encoding");
229 QTest::addColumn<QByteArray>("actual");
230 QTest::addColumn<bool>("supported");
231
232 QTest::newRow("null") << QByteArray() << QByteArray("ISO-8859-15") << false;
233 QTest::newRow("empty") << QByteArray("") << QByteArray("ISO-8859-15") << false;
234 QTest::newRow("space") << QByteArray(" ") << QByteArray("ISO-8859-15") << false;
235 QTest::newRow("invalid") << QByteArray("invalid") << QByteArray("ISO-8859-15") << false;
236 foreach (const QByteArray& codec, QTextCodec::availableCodecs())
237 QTest::newRow(codec) << codec << codec << true;
238 }
239
testEncoding()240 void tst_IrcMessage::testEncoding()
241 {
242 QFETCH(QByteArray, encoding);
243 QFETCH(QByteArray, actual);
244 QFETCH(bool, supported);
245
246 if (!supported)
247 QTest::ignoreMessage(QtWarningMsg, "IrcMessage::setEncoding(): unsupported encoding \"" + encoding + "\" ");
248
249 IrcMessage msg(nullptr);
250 msg.setEncoding(encoding);
251 QCOMPARE(msg.encoding(), actual);
252 }
253
testDecoder_data()254 void tst_IrcMessage::testDecoder_data()
255 {
256 QTest::addColumn<QByteArray>("encoding");
257 QTest::addColumn<QByteArray>("base64");
258
259 QTest::newRow("windows-1251") << QByteArray("windows-1251") << QByteArray("7+Xt8eju7eXw4Owg7+7k5OXr/O375Q==");
260 QTest::newRow("EUC-JP") << QByteArray("EUC-JP") << QByteArray("pKSkxKTHpOKkyaSzpMek4qGhpbml3qXbyMc=");
261 QTest::newRow("Shift-JIS") << QByteArray("Shift-JIS") << QByteArray("lbaOmoNSgVuDaJVcg1aDdINn");
262 QTest::newRow("ISO-8859-15") << QByteArray("ISO-8859-15") << QByteArray("5Gl0aWVucORpduQ="); // TODO: QByteArray("5OQ=");
263 }
264
testDecoder()265 void tst_IrcMessage::testDecoder()
266 {
267 QFETCH(QByteArray, encoding);
268 QFETCH(QByteArray, base64);
269
270 #ifdef Q_OS_LINUX
271 // others have problems with symbols (win) or private headers (osx frameworks)
272 IrcMessageDecoder decoder;
273 QString actual = decoder.decode(QByteArray::fromBase64(base64), encoding);
274 QString expected = QTextCodec::codecForName(encoding)->toUnicode(QByteArray::fromBase64(base64));
275 QCOMPARE(actual, expected);
276 #endif // Q_OS_LINUX
277 }
278
testTags()279 void tst_IrcMessage::testTags()
280 {
281 QVariantMap tags;
282 tags.insert("aaa", "bbb");
283 tags.insert("ccc", "");
284 tags.insert("example.com/ddd", "eee");
285
286 IrcConnection connection;
287 IrcMessage* message = IrcMessage::fromData("@aaa=bbb;ccc;example.com/ddd=eee :nick!ident@host.com PRIVMSG me :Hello", &connection);
288 QCOMPARE(message->tags(), tags);
289
290 tags.insert("ccc", "xyz");
291 message->setTag("ccc", "xyz");
292
293 QCOMPARE(message->tags(), tags);
294 QCOMPARE(message->toData(), QByteArray("@aaa=bbb;ccc=xyz;example.com/ddd=eee :nick!ident@host.com PRIVMSG me Hello"));
295
296 tags.insert("fff", "ggg");
297 message->setTag("fff", "ggg");
298 QCOMPARE(message->tags(), tags);
299 QCOMPARE(message->toData(), QByteArray("@aaa=bbb;ccc=xyz;example.com/ddd=eee;fff=ggg :nick!ident@host.com PRIVMSG me Hello"));
300
301 tags.clear();
302 tags.insert("foo", "bar");
303 message->setTags(tags);
304 QCOMPARE(message->tags(), tags);
305 QCOMPARE(message->toData(), QByteArray("@foo=bar :nick!ident@host.com PRIVMSG me Hello"));
306 }
307
testServerTime()308 void tst_IrcMessage::testServerTime()
309 {
310 IrcConnection connection;
311 IrcMessage* message = IrcMessage::fromData("@time=2011-10-19T16:40:51.620Z :Angel!angel@example.org PRIVMSG Wiz :Hello", &connection);
312 QCOMPARE(message->timeStamp(), QDateTime(QDate(2011, 10, 19), QTime(16, 40, 51, 620), Qt::UTC));
313 }
314
testAccount_data()315 void tst_IrcMessage::testAccount_data()
316 {
317 QTest::addColumn<QByteArray>("data");
318 QTest::addColumn<QString>("account");
319
320 QTest::newRow("no account") << QByteArray(":nick!ident@host.com PRIVMSG me :Hello") << QString();
321 QTest::newRow("has account") << QByteArray("@account=jpnurmi :nick!ident@host.com PRIVMSG me :Hello") << QString("jpnurmi");
322 }
323
testAccount()324 void tst_IrcMessage::testAccount()
325 {
326 QFETCH(QByteArray, data);
327 QFETCH(QString, account);
328
329 IrcConnection connection;
330 IrcMessage* message = IrcMessage::fromData(data, &connection);
331 QCOMPARE(message->account(), account);
332 }
333
testAccountMessage_data()334 void tst_IrcMessage::testAccountMessage_data()
335 {
336 QTest::addColumn<bool>("valid");
337 QTest::addColumn<QByteArray>("data");
338 QTest::addColumn<QString>("account");
339
340 QTest::newRow("no prefix") << false << QByteArray("ACCOUNT") << QString();
341 QTest::newRow("empty prefix") << false << QByteArray(": ACCOUNT") << QString();
342 QTest::newRow("no params") << false << QByteArray(":nick!ident@host ACCOUNT") << QString();
343 QTest::newRow("identified") << true << QByteArray(":nick!ident@host ACCOUNT account") << QString("account");
344 QTest::newRow("unidentified") << true << QByteArray(":nick!ident@host ACCOUNT *") << QString();
345 }
346
testAccountMessage()347 void tst_IrcMessage::testAccountMessage()
348 {
349 QFETCH(bool, valid);
350 QFETCH(QByteArray, data);
351 QFETCH(QString, account);
352
353 IrcConnection connection;
354 IrcMessage* message = IrcMessage::fromData(data, &connection);
355 QCOMPARE(message->type(), IrcMessage::Account);
356 QCOMPARE(message->command(), QString("ACCOUNT"));
357 QCOMPARE(message->property("valid").toBool(), valid);
358 QCOMPARE(message->property("account").toString(), account);
359
360 IrcAccountMessage* accountMessage = qobject_cast<IrcAccountMessage*>(message);
361 QVERIFY(accountMessage);
362 QCOMPARE(accountMessage->isValid(), valid);
363 QCOMPARE(accountMessage->account(), account);
364 }
365
testAwayMessage_data()366 void tst_IrcMessage::testAwayMessage_data()
367 {
368 QTest::addColumn<bool>("valid");
369 QTest::addColumn<QByteArray>("data");
370 QTest::addColumn<QString>("content");
371
372 QTest::newRow("no prefix") << true << QByteArray("AWAY") << QString();
373 QTest::newRow("empty prefix") << false << QByteArray(": AWAY") << QString();
374 QTest::newRow("away") << true << QByteArray(":nick!ident@host AWAY :gone far away") << QString("gone far away");
375 QTest::newRow("back") << true << QByteArray(":nick!ident@host AWAY") << QString();
376 }
377
testAwayMessage()378 void tst_IrcMessage::testAwayMessage()
379 {
380 QFETCH(bool, valid);
381 QFETCH(QByteArray, data);
382 QFETCH(QString, content);
383
384 IrcConnection connection;
385 IrcMessage* message = IrcMessage::fromData(data, &connection);
386 QCOMPARE(message->type(), IrcMessage::Away);
387 QCOMPARE(message->command(), QString("AWAY"));
388 QCOMPARE(message->property("valid").toBool(), valid);
389 QCOMPARE(message->property("content").toString(), content);
390 QCOMPARE(message->property("away").toBool(), !content.isEmpty());
391 QVERIFY(!message->property("reply").toBool());
392
393 IrcAwayMessage* awayMessage = qobject_cast<IrcAwayMessage*>(message);
394 QVERIFY(awayMessage);
395 QCOMPARE(awayMessage->isValid(), valid);
396 QCOMPARE(awayMessage->content(), content);
397 QCOMPARE(awayMessage->isAway(), !content.isEmpty());
398 QVERIFY(!awayMessage->isReply());
399 }
400
testCapabilityMessage_data()401 void tst_IrcMessage::testCapabilityMessage_data()
402 {
403 QTest::addColumn<bool>("valid");
404 QTest::addColumn<QByteArray>("data");
405 QTest::addColumn<QString>("subCommand");
406 QTest::addColumn<QStringList>("capabilities");
407
408 QTest::newRow("no prefix") << true << QByteArray("CAP") << QString() << QStringList();
409 QTest::newRow("empty prefix") << false << QByteArray(": CAP") << QString() << QStringList();
410 QTest::newRow("no params") << true << QByteArray(":server CAP") << QString() << QStringList();
411
412 QTest::newRow("ls") << true << QByteArray(":server CAP * LS :identify-msg sasl") << QString("LS") << (QStringList() << "identify-msg" << "sasl");
413 QTest::newRow("ack") << true << QByteArray(":server CAP communi ACK :identify-msg") << QString("ACK") << (QStringList() << "identify-msg");
414 QTest::newRow("nak") << true << QByteArray(":server CAP communi NAK :sasl") << QString("NAK") << (QStringList() << "sasl");
415 }
416
testCapabilityMessage()417 void tst_IrcMessage::testCapabilityMessage()
418 {
419 QFETCH(bool, valid);
420 QFETCH(QByteArray, data);
421 QFETCH(QString, subCommand);
422 QFETCH(QStringList, capabilities);
423
424 IrcConnection connection;
425 IrcMessage* message = IrcMessage::fromData(data, &connection);
426 QCOMPARE(message->type(), IrcMessage::Capability);
427 QCOMPARE(message->command(), QString("CAP"));
428 QCOMPARE(message->property("valid").toBool(), valid);
429 QCOMPARE(message->property("subCommand").toString(), subCommand);
430 QCOMPARE(message->property("capabilities").toStringList(), capabilities);
431
432 IrcCapabilityMessage* capabilityMessage = qobject_cast<IrcCapabilityMessage*>(message);
433 QVERIFY(capabilityMessage);
434 QCOMPARE(capabilityMessage->isValid(), valid);
435 QCOMPARE(capabilityMessage->subCommand(), subCommand);
436 QCOMPARE(capabilityMessage->capabilities(), capabilities);
437 }
438
testErrorMessage_data()439 void tst_IrcMessage::testErrorMessage_data()
440 {
441 QTest::addColumn<bool>("valid");
442 QTest::addColumn<QByteArray>("data");
443 QTest::addColumn<QString>("error");
444
445 QTest::newRow("no prefix") << true << QByteArray("ERROR error1") << QString("error1");
446 QTest::newRow("empty prefix") << false << QByteArray(": ERROR error1") << QString("error1");
447 QTest::newRow("no params") << false << QByteArray(":server ERROR") << QString();
448 QTest::newRow("all ok") << true << QByteArray(":server ERROR error1") << QString("error1");
449 }
450
testErrorMessage()451 void tst_IrcMessage::testErrorMessage()
452 {
453 QFETCH(bool, valid);
454 QFETCH(QByteArray, data);
455 QFETCH(QString, error);
456
457 IrcConnection connection;
458 IrcMessage* message = IrcMessage::fromData(data, &connection);
459 QCOMPARE(message->type(), IrcMessage::Error);
460 QCOMPARE(message->command(), QString("ERROR"));
461 QCOMPARE(message->property("valid").toBool(), valid);
462 QCOMPARE(message->property("error").toString(), error);
463
464 IrcErrorMessage* errorMessage = qobject_cast<IrcErrorMessage*>(message);
465 QVERIFY(errorMessage);
466 QCOMPARE(errorMessage->isValid(), valid);
467 QCOMPARE(errorMessage->error(), error);
468 }
469
testHostChangeMessage_data()470 void tst_IrcMessage::testHostChangeMessage_data()
471 {
472 QTest::addColumn<bool>("valid");
473 QTest::addColumn<QByteArray>("data");
474 QTest::addColumn<QString>("user");
475 QTest::addColumn<QString>("host");
476
477 QTest::newRow("no prefix") << true << QByteArray("CHGHOST newuser newhost") << QString("newuser") << QString("newhost");
478 QTest::newRow("empty prefix") << false << QByteArray(": CHGHOST newuser newhost") << QString("newuser") << QString("newhost");
479 QTest::newRow("no params") << false << QByteArray(":nick!user@host CHGHOST") << QString() << QString();
480 QTest::newRow("all ok") << true << QByteArray(":nick!user@host CHGHOST newuser newhost") << QString("newuser") << QString("newhost");
481 }
482
testHostChangeMessage()483 void tst_IrcMessage::testHostChangeMessage()
484 {
485 QFETCH(bool, valid);
486 QFETCH(QByteArray, data);
487 QFETCH(QString, user);
488 QFETCH(QString, host);
489
490 IrcConnection connection;
491 IrcMessage* message = IrcMessage::fromData(data, &connection);
492 QCOMPARE(message->type(), IrcMessage::HostChange);
493 QCOMPARE(message->command(), QString("CHGHOST"));
494 QCOMPARE(message->property("valid").toBool(), valid);
495 QCOMPARE(message->property("user").toString(), user);
496 QCOMPARE(message->property("host").toString(), host);
497
498 IrcHostChangeMessage* chghostMessage = qobject_cast<IrcHostChangeMessage*>(message);
499 QVERIFY(chghostMessage);
500 QCOMPARE(chghostMessage->isValid(), valid);
501 QCOMPARE(chghostMessage->user(), user);
502 QCOMPARE(chghostMessage->host(), host);
503 }
504
testInviteMessage_data()505 void tst_IrcMessage::testInviteMessage_data()
506 {
507 QTest::addColumn<bool>("valid");
508 QTest::addColumn<QByteArray>("data");
509 QTest::addColumn<QString>("user");
510 QTest::addColumn<QString>("channel");
511
512 QTest::newRow("no prefix") << true << QByteArray("INVITE Wiz #Dust") << QString("Wiz") << QString("#Dust");
513 QTest::newRow("empty prefix") << false << QByteArray(": INVITE Wiz #Dust") << QString("Wiz") << QString("#Dust");
514 QTest::newRow("no params") << false << QByteArray(":Angel INVITE") << QString() << QString();
515 QTest::newRow("no channel") << false << QByteArray(":Angel INVITE Wiz") << QString("Wiz") << QString();
516 QTest::newRow("all ok") << true << QByteArray(":Angel INVITE Wiz #Dust") << QString("Wiz") << QString("#Dust");
517 }
518
testInviteMessage()519 void tst_IrcMessage::testInviteMessage()
520 {
521 QFETCH(bool, valid);
522 QFETCH(QByteArray, data);
523 QFETCH(QString, channel);
524 QFETCH(QString, user);
525
526 IrcConnection connection;
527 IrcMessage* message = IrcMessage::fromData(data, &connection);
528 QCOMPARE(message->type(), IrcMessage::Invite);
529 QCOMPARE(message->command(), QString("INVITE"));
530 QCOMPARE(message->property("valid").toBool(), valid);
531 QCOMPARE(message->property("channel").toString(), channel);
532 QCOMPARE(message->property("user").toString(), user);
533
534 IrcInviteMessage* inviteMessage = qobject_cast<IrcInviteMessage*>(message);
535 QVERIFY(inviteMessage);
536 QCOMPARE(inviteMessage->isValid(), valid);
537 QCOMPARE(inviteMessage->channel(), channel);
538 QCOMPARE(inviteMessage->user(), user);
539 }
540
testJoinMessage_data()541 void tst_IrcMessage::testJoinMessage_data()
542 {
543 QTest::addColumn<bool>("valid");
544 QTest::addColumn<QByteArray>("data");
545 QTest::addColumn<QString>("channel");
546 QTest::addColumn<QString>("account");
547 QTest::addColumn<QString>("realName");
548
549 QTest::newRow("no prefix") << true << QByteArray("JOIN #Twilight_zone") << QString("#Twilight_zone") << QString() << QString();
550 QTest::newRow("empty prefix") << false << QByteArray(": JOIN #Twilight_zone") << QString("#Twilight_zone") << QString() << QString();
551 QTest::newRow("no params") << false << QByteArray(":WiZ JOIN") << QString() << QString() << QString();
552 QTest::newRow("all ok") << true << QByteArray(":WiZ JOIN #Twilight_zone") << QString("#Twilight_zone") << QString() << QString();
553
554 QTest::newRow("extended-join") << true << QByteArray(":nick!user@host JOIN #channelname accountname :Real Name") << QString("#channelname") << QString("accountname") << QString("Real Name");
555 QTest::newRow("unidentified") << true << QByteArray(":nick!user@host JOIN #channelname * :Real Name") << QString("#channelname") << QString() << QString("Real Name");
556 }
557
testJoinMessage()558 void tst_IrcMessage::testJoinMessage()
559 {
560 QFETCH(bool, valid);
561 QFETCH(QByteArray, data);
562 QFETCH(QString, channel);
563 QFETCH(QString, account);
564 QFETCH(QString, realName);
565
566 IrcConnection connection;
567 IrcMessage* message = IrcMessage::fromData(data, &connection);
568 QCOMPARE(message->type(), IrcMessage::Join);
569 QCOMPARE(message->command(), QString("JOIN"));
570 QCOMPARE(message->property("valid").toBool(), valid);
571 QCOMPARE(message->property("channel").toString(), channel);
572 QCOMPARE(message->property("account").toString(), account);
573 QCOMPARE(message->property("realName").toString(), realName);
574
575 IrcJoinMessage* joinMessage = qobject_cast<IrcJoinMessage*>(message);
576 QVERIFY(joinMessage);
577 QCOMPARE(joinMessage->isValid(), valid);
578 QCOMPARE(joinMessage->channel(), channel);
579 QCOMPARE(joinMessage->account(), account);
580 QCOMPARE(joinMessage->realName(), realName);
581 }
582
testKickMessage_data()583 void tst_IrcMessage::testKickMessage_data()
584 {
585 QTest::addColumn<bool>("valid");
586 QTest::addColumn<QByteArray>("data");
587 QTest::addColumn<QString>("channel");
588 QTest::addColumn<QString>("user");
589 QTest::addColumn<QString>("reason");
590
591 QTest::newRow("no prefix") << true << QByteArray("KICK #Finnish John") << QString("#Finnish") << QString("John") << QString();
592 QTest::newRow("empty prefix") << false << QByteArray(": KICK #Finnish John") << QString("#Finnish") << QString("John") << QString();
593 QTest::newRow("no params") << false << QByteArray(":WiZ KICK") << QString() << QString() << QString();
594 QTest::newRow("no user") << false << QByteArray(":WiZ KICK #Finnish") << QString("#Finnish") << QString() << QString();
595 QTest::newRow("no reason") << true << QByteArray(":WiZ KICK #Finnish John") << QString("#Finnish") << QString("John") << QString();
596 QTest::newRow("all ok") << true << QByteArray(":WiZ KICK #Finnish John :Another reason") << QString("#Finnish") << QString("John") << QString("Another reason");
597 }
598
testKickMessage()599 void tst_IrcMessage::testKickMessage()
600 {
601 QFETCH(bool, valid);
602 QFETCH(QByteArray, data);
603 QFETCH(QString, channel);
604 QFETCH(QString, user);
605 QFETCH(QString, reason);
606
607 IrcConnection connection;
608 IrcMessage* message = IrcMessage::fromData(data, &connection);
609 QCOMPARE(message->type(), IrcMessage::Kick);
610 QCOMPARE(message->command(), QString("KICK"));
611 QCOMPARE(message->property("valid").toBool(), valid);
612 QCOMPARE(message->property("channel").toString(), channel);
613 QCOMPARE(message->property("user").toString(), user);
614 QCOMPARE(message->property("reason").toString(), reason);
615
616 IrcKickMessage* kickMessage = qobject_cast<IrcKickMessage*>(message);
617 QVERIFY(kickMessage);
618 QCOMPARE(kickMessage->isValid(), valid);
619 QCOMPARE(kickMessage->channel(), channel);
620 QCOMPARE(kickMessage->user(), user);
621 QCOMPARE(kickMessage->reason(), reason);
622 }
623
testNamesMessage()624 void tst_IrcMessage::testNamesMessage()
625 {
626 IrcConnection connection;
627 IrcNamesMessage message(&connection);
628 message.setPrefix("nick!ident@host");
629 message.setParameters(QStringList() << "chan" << "usr1" << "usr2" << "usr3");
630 QVERIFY(message.isValid());
631 QCOMPARE(message.type(), IrcMessage::Names);
632 QCOMPARE(message.command(), QString("NAMES"));
633 QCOMPARE(message.channel(), QString("chan"));
634 QCOMPARE(message.names(), QStringList() << "usr1" << "usr2" << "usr3");
635 }
636
testNickMessage_data()637 void tst_IrcMessage::testNickMessage_data()
638 {
639 QTest::addColumn<bool>("valid");
640 QTest::addColumn<QByteArray>("data");
641 QTest::addColumn<QString>("oldNick");
642 QTest::addColumn<QString>("newNick");
643
644 QTest::newRow("no prefix") << true << QByteArray("NICK Kilroy") << QString() << QString("Kilroy");
645 QTest::newRow("empty prefix") << false << QByteArray(": NICK Kilroy") << QString() << QString("Kilroy");
646 QTest::newRow("no params") << false << QByteArray(":WiZ NICK") << QString("WiZ") << QString();
647 QTest::newRow("all ok") << true << QByteArray(":WiZ NICK Kilroy") << QString("WiZ") << QString("Kilroy");
648 }
649
testNickMessage()650 void tst_IrcMessage::testNickMessage()
651 {
652 QFETCH(bool, valid);
653 QFETCH(QByteArray, data);
654 QFETCH(QString, oldNick);
655 QFETCH(QString, newNick);
656
657 IrcConnection connection;
658 IrcMessage* message = IrcMessage::fromData(data, &connection);
659 QCOMPARE(message->type(), IrcMessage::Nick);
660 QCOMPARE(message->command(), QString("NICK"));
661 QCOMPARE(message->property("valid").toBool(), valid);
662 QCOMPARE(message->property("oldNick").toString(), oldNick);
663 QCOMPARE(message->property("newNick").toString(), newNick);
664
665 IrcNickMessage* nickMessage = qobject_cast<IrcNickMessage*>(message);
666 QVERIFY(nickMessage);
667 QCOMPARE(nickMessage->isValid(), valid);
668 QCOMPARE(nickMessage->oldNick(), oldNick);
669 QCOMPARE(nickMessage->newNick(), newNick);
670 }
671
testNoticeMessage_data()672 void tst_IrcMessage::testNoticeMessage_data()
673 {
674 QTest::addColumn<bool>("valid");
675 QTest::addColumn<QByteArray>("data");
676 QTest::addColumn<QString>("target");
677 QTest::addColumn<QString>("content");
678 QTest::addColumn<bool>("priv");
679 QTest::addColumn<bool>("reply");
680
681 QTest::newRow("no prefix") << true << QByteArray("NOTICE Wiz :Hello are you receiving this message ?") << QString("Wiz") << QString("Hello are you receiving this message ?") << false << false;
682 QTest::newRow("empty prefix") << false << QByteArray(": NOTICE Wiz :Hello are you receiving this message ?") << QString("Wiz") << QString("Hello are you receiving this message ?") << false << false;
683 QTest::newRow("no params") << false << QByteArray(":Angel NOTICE Wiz") << QString("Wiz") << QString() << false << false;
684 QTest::newRow("all ok") << true << QByteArray(":Angel NOTICE Wiz :Hello are you receiving this message ?") << QString("Wiz") << QString("Hello are you receiving this message ?") << false << false;
685 QTest::newRow("private") << true << QByteArray(":Angel NOTICE communi :Hello are you receiving this message ?") << QString("communi") << QString("Hello are you receiving this message ?") << true << false;
686 QTest::newRow("reply") << true << QByteArray(":Angel NOTICE Wiz :\1Hello are you receiving this message ?\1") << QString("Wiz") << QString("Hello are you receiving this message ?") << false << true;
687 }
688
testNoticeMessage()689 void tst_IrcMessage::testNoticeMessage()
690 {
691 QFETCH(bool, valid);
692 QFETCH(QByteArray, data);
693 QFETCH(QString, target);
694 QFETCH(QString, content);
695 QFETCH(bool, priv);
696 QFETCH(bool, reply);
697
698 IrcConnection connection;
699 connection.setNickName("communi");
700 IrcMessage* message = IrcMessage::fromData(data, &connection);
701 QCOMPARE(message->type(), IrcMessage::Notice);
702 QCOMPARE(message->command(), QString("NOTICE"));
703 QCOMPARE(message->property("valid").toBool(), valid);
704 QCOMPARE(message->property("target").toString(), target);
705 QCOMPARE(message->property("content").toString(), content);
706 QCOMPARE(message->property("private").toBool(), priv);
707 QCOMPARE(message->property("reply").toBool(), reply);
708
709 IrcNoticeMessage* noticeMessage = qobject_cast<IrcNoticeMessage*>(message);
710 QVERIFY(noticeMessage);
711 QCOMPARE(noticeMessage->isValid(), valid);
712 QCOMPARE(noticeMessage->target(), target);
713 QCOMPARE(noticeMessage->content(), content);
714 QCOMPARE(noticeMessage->isPrivate(), priv);
715 QCOMPARE(noticeMessage->isReply(), reply);
716 }
717
testNumericMessage_data()718 void tst_IrcMessage::testNumericMessage_data()
719 {
720 QTest::addColumn<bool>("valid");
721 QTest::addColumn<QByteArray>("data");
722 QTest::addColumn<int>("code");
723 QTest::addColumn<bool>("composed");
724
725 QTest::newRow("no prefix") << true << QByteArray("123 Kilroy") << 123 << false;
726 QTest::newRow("empty prefix") << false << QByteArray(": 123 Kilroy") << 123 << false;
727 QTest::newRow("no params") << true << QByteArray(":WiZ 456") << 456 << false;
728 QTest::newRow("all ok") << true << QByteArray(":WiZ 789 Kilroy") << 789 << false;
729 QTest::newRow("composed") << true << QByteArray(":server 352 me someone ...") << 352 << true;
730 }
731
testNumericMessage()732 void tst_IrcMessage::testNumericMessage()
733 {
734 QFETCH(bool, valid);
735 QFETCH(QByteArray, data);
736 QFETCH(int, code);
737 QFETCH(bool, composed);
738
739 IrcConnection connection;
740 IrcMessage* message = IrcMessage::fromData(data, &connection);
741 QCOMPARE(message->type(), IrcMessage::Numeric);
742 QVERIFY(message->command().toInt() > 0);
743 QCOMPARE(message->property("valid").toBool(), valid);
744 QCOMPARE(message->property("code").toInt(), code);
745 QCOMPARE(message->property("composed").toBool(), composed);
746
747 IrcNumericMessage* numericMessage = qobject_cast<IrcNumericMessage*>(message);
748 QVERIFY(numericMessage);
749 QCOMPARE(numericMessage->isValid(), valid);
750 QCOMPARE(numericMessage->code(), code);
751 QCOMPARE(numericMessage->isComposed(), composed);
752 }
753
testModeMessage_data()754 void tst_IrcMessage::testModeMessage_data()
755 {
756 QTest::addColumn<bool>("valid");
757 QTest::addColumn<QByteArray>("data");
758 QTest::addColumn<QString>("target");
759 QTest::addColumn<QString>("mode");
760 QTest::addColumn<QString>("argument");
761
762 QTest::newRow("no prefix") << true << QByteArray("MODE Kilroy -w") << QString("Kilroy") << QString("-w") << QString();
763 QTest::newRow("empty prefix") << false << QByteArray(": MODE Kilroy -w") << QString("Kilroy") << QString("-w") << QString();
764 QTest::newRow("no params") << false << QByteArray(":WiZ MODE Kilroy") << QString("Kilroy") << QString() << QString();
765 QTest::newRow("all ok") << true << QByteArray(":WiZ MODE Kilroy -w") << QString("Kilroy") << QString("-w") << QString();
766
767 QTest::newRow("1") << true << QByteArray(":WiZ MODE #Finnish +im") << QString("#Finnish") << QString("+im") << QString();
768 QTest::newRow("2") << true << QByteArray(":Angel MODE #Finnish +o Kilroy") << QString("#Finnish") << QString("+o") << QString("Kilroy");
769 QTest::newRow("3") << true << QByteArray(":Kilroy MODE #Finnish +v Wiz") << QString("#Finnish") << QString("+v") << QString("Wiz");
770 QTest::newRow("4a") << true << QByteArray("MODE #Fins -s") << QString("#Fins") << QString("-s") << QString();
771 QTest::newRow("4b") << false << QByteArray(": MODE #Fins -s") << QString("#Fins") << QString("-s") << QString();
772 QTest::newRow("5") << true << QByteArray(":WiZ MODE #42 +k oulu") << QString("#42") << QString("+k") << QString("oulu");
773 QTest::newRow("6a") << true << QByteArray("MODE #eu-opers +l 10") << QString("#eu-opers") << QString("+l") << QString("10");
774 QTest::newRow("6b") << false << QByteArray(": MODE #eu-opers +l 10") << QString("#eu-opers") << QString("+l") << QString("10");
775 QTest::newRow("7") << true << QByteArray(":nobody MODE &oulu +b") << QString("&oulu") << QString("+b") << QString();
776 QTest::newRow("8") << true << QByteArray(":someone MODE &oulu +b *!*@*") << QString("&oulu") << QString("+b") << QString("*!*@*");
777 QTest::newRow("9") << true << QByteArray(":anyone MODE &oulu +b *!*@*.edu") << QString("&oulu") << QString("+b") << QString("*!*@*.edu");
778 QTest::newRow("10a") << true << QByteArray("MODE WiZ -w") << QString("WiZ") << QString("-w") << QString();
779 QTest::newRow("10b") << false << QByteArray(": MODE WiZ -w") << QString("WiZ") << QString("-w") << QString();
780 QTest::newRow("11") << true << QByteArray(":Angel MODE Angel +i") << QString("Angel") << QString("+i") << QString();
781 QTest::newRow("12") << true << QByteArray(":WiZ MODE WiZ -o") << QString("WiZ") << QString("-o") << QString();
782
783 QTest::newRow("args") << true << QByteArray(":someone MODE #chan +lk 10 secret") << QString("#chan") << QString("+lk") << QString("10 secret");
784 }
785
testModeMessage()786 void tst_IrcMessage::testModeMessage()
787 {
788 QFETCH(bool, valid);
789 QFETCH(QByteArray, data);
790 QFETCH(QString, target);
791 QFETCH(QString, mode);
792 QFETCH(QString, argument);
793
794 #if (QT_VERSION) >= (QT_VERSION_CHECK(5, 14, 0))
795 const QString arg = argument.split(" ", Qt::SkipEmptyParts).value(0);
796 const QStringList args = argument.split(" ", Qt::SkipEmptyParts);
797 #else
798 const QString arg = argument.split(" ", QString::SkipEmptyParts).value(0);
799 const QStringList args = argument.split(" ", QString::SkipEmptyParts);
800 #endif
801
802 IrcConnection connection;
803 IrcMessage* message = IrcMessage::fromData(data, &connection);
804 QCOMPARE(message->type(), IrcMessage::Mode);
805 QCOMPARE(message->command(), QString("MODE"));
806 QCOMPARE(message->property("valid").toBool(), valid);
807 QCOMPARE(message->property("target").toString(), target);
808 QCOMPARE(message->property("mode").toString(), mode);
809 QCOMPARE(message->property("argument").toString(), arg);
810 QCOMPARE(message->property("arguments").toStringList(), args);
811
812 IrcModeMessage* modeMessage = qobject_cast<IrcModeMessage*>(message);
813 QVERIFY(modeMessage);
814 QCOMPARE(modeMessage->isValid(), valid);
815 QCOMPARE(modeMessage->target(), target);
816 QCOMPARE(modeMessage->mode(), mode);
817 QCOMPARE(modeMessage->argument(), arg);
818 QCOMPARE(modeMessage->arguments(), args);
819 }
820
testMotdMessage()821 void tst_IrcMessage::testMotdMessage()
822 {
823 IrcConnection connection;
824 IrcMotdMessage message(&connection);
825 message.setPrefix("nick!ident@host");
826 QStringList params;
827 params += "user";
828 params += ":server 375 user :- server Message of the Day";
829 params += ":server 372 user :- Welcome...";
830 params += ":server 376 user :End of /MOTD command";
831 message.setParameters(params);
832 QVERIFY(message.isValid());
833 QCOMPARE(message.type(), IrcMessage::Motd);
834 QCOMPARE(message.command(), QString("MOTD"));
835 QCOMPARE(message.lines(), QStringList(params.mid(1)));
836 }
837
testPartMessage_data()838 void tst_IrcMessage::testPartMessage_data()
839 {
840 QTest::addColumn<bool>("valid");
841 QTest::addColumn<QByteArray>("data");
842 QTest::addColumn<QString>("channel");
843 QTest::addColumn<QString>("reason");
844
845 QTest::newRow("no prefix") << true << QByteArray("PART #Twilight_zone") << QString("#Twilight_zone") << QString();
846 QTest::newRow("empty prefix") << false << QByteArray(": PART #Twilight_zone") << QString("#Twilight_zone") << QString();
847 QTest::newRow("no params") << false << QByteArray(":WiZ PART") << QString() << QString();
848 QTest::newRow("no reason") << true << QByteArray(":WiZ PART #Twilight_zone") << QString("#Twilight_zone") << QString();
849 QTest::newRow("all ok") << true << QByteArray(":WiZ PART #Twilight_zone :Gone to have lunch") << QString("#Twilight_zone") << QString("Gone to have lunch");
850 }
851
testPartMessage()852 void tst_IrcMessage::testPartMessage()
853 {
854 QFETCH(bool, valid);
855 QFETCH(QByteArray, data);
856 QFETCH(QString, channel);
857 QFETCH(QString, reason);
858
859 IrcConnection connection;
860 IrcMessage* message = IrcMessage::fromData(data, &connection);
861 QCOMPARE(message->type(), IrcMessage::Part);
862 QCOMPARE(message->command(), QString("PART"));
863 QCOMPARE(message->property("valid").toBool(), valid);
864 QCOMPARE(message->property("channel").toString(), channel);
865 QCOMPARE(message->property("reason").toString(), reason);
866
867 IrcPartMessage* partMessage = qobject_cast<IrcPartMessage*>(message);
868 QVERIFY(partMessage);
869 QCOMPARE(partMessage->isValid(), valid);
870 QCOMPARE(partMessage->channel(), channel);
871 QCOMPARE(partMessage->reason(), reason);
872 }
873
testPingMessage()874 void tst_IrcMessage::testPingMessage()
875 {
876 IrcConnection connection;
877 IrcMessage* message = IrcMessage::fromData("PING :arg", &connection);
878 QCOMPARE(message->type(), IrcMessage::Ping);
879 QCOMPARE(message->command(), QString("PING"));
880 QCOMPARE(message->property("command").toString(), QString("PING"));
881 QVERIFY(message->property("valid").toBool());
882 QCOMPARE(message->property("argument").toString(), QString("arg"));
883
884 IrcPingMessage* pingMessage = qobject_cast<IrcPingMessage*>(message);
885 QVERIFY(pingMessage);
886 QVERIFY(pingMessage->isValid());
887 QCOMPARE(pingMessage->argument(), QString("arg"));
888 }
889
testPongMessage()890 void tst_IrcMessage::testPongMessage()
891 {
892 IrcConnection connection;
893 IrcMessage* message = IrcMessage::fromData("PONG tgt :arg", &connection);
894 QCOMPARE(message->type(), IrcMessage::Pong);
895 QCOMPARE(message->command(), QString("PONG"));
896 QCOMPARE(message->property("command").toString(), QString("PONG"));
897 QVERIFY(message->property("valid").toBool());
898 QCOMPARE(message->property("argument").toString(), QString("arg"));
899
900 IrcPongMessage* pongMessage = qobject_cast<IrcPongMessage*>(message);
901 QVERIFY(pongMessage);
902 QVERIFY(pongMessage->isValid());
903 QCOMPARE(pongMessage->argument(), QString("arg"));
904 }
905
testPrivateMessage_data()906 void tst_IrcMessage::testPrivateMessage_data()
907 {
908 QTest::addColumn<bool>("valid");
909 QTest::addColumn<QString>("cap");
910 QTest::addColumn<QByteArray>("data");
911 QTest::addColumn<QString>("target");
912 QTest::addColumn<QString>("content");
913 QTest::addColumn<bool>("priv");
914 QTest::addColumn<bool>("action");
915 QTest::addColumn<bool>("request");
916 QTest::addColumn<uint>("flags");
917
918 QTest::newRow("no prefix") << true << QString() << QByteArray("PRIVMSG Wiz :Hello are you receiving this message ?") << QString("Wiz") << QString("Hello are you receiving this message ?") << false << false << false << static_cast<uint>(IrcMessage::None);
919 QTest::newRow("empty prefix") << false << QString() << QByteArray(": PRIVMSG Wiz :Hello are you receiving this message ?") << QString("Wiz") << QString("Hello are you receiving this message ?") << false << false << false << static_cast<uint>(IrcMessage::None);
920 QTest::newRow("no params") << false << QString() << QByteArray(":Angel PRIVMSG Wiz") << QString("Wiz") << QString() << false << false << false << static_cast<uint>(IrcMessage::None);
921 QTest::newRow("all ok") << true << QString() << QByteArray(":Angel PRIVMSG Wiz :Hello are you receiving this message ?") << QString("Wiz") << QString("Hello are you receiving this message ?") << false << false << false << static_cast<uint>(IrcMessage::None);
922 QTest::newRow("private") << true << QString() << QByteArray(":Angel PRIVMSG communi :Hello are you receiving this message ?") << QString("communi") << QString("Hello are you receiving this message ?") << true << false << false << static_cast<uint>(IrcMessage::None);
923 QTest::newRow("action") << true << QString() << QByteArray(":Angel PRIVMSG Wiz :\1ACTION Hello are you receiving this message ?\1") << QString("Wiz") << QString("Hello are you receiving this message ?") << false << true << false << static_cast<uint>(IrcMessage::None);
924 QTest::newRow("request") << true << QString() << QByteArray(":Angel PRIVMSG Wiz :\1Hello are you receiving this message ?\1") << QString("Wiz") << QString("Hello are you receiving this message ?") << false << false << true << static_cast<uint>(IrcMessage::None);
925 }
926
927 class TestProtocol : public IrcProtocol
928 {
929 public:
TestProtocol(const QString & cap,IrcConnection * connection)930 TestProtocol(const QString& cap, IrcConnection* connection) : IrcProtocol(connection)
931 {
932 QSet<QString> caps;
933 caps.insert(cap);
934 setAvailableCapabilities(caps);
935 setActiveCapabilities(caps);
936 }
937 };
938
939 class FriendConnection : public IrcConnection
940 {
941 friend class tst_IrcMessage;
942 };
943
testPrivateMessage()944 void tst_IrcMessage::testPrivateMessage()
945 {
946 QFETCH(bool, valid);
947 QFETCH(QString, cap);
948 QFETCH(QByteArray, data);
949 QFETCH(QString, target);
950 QFETCH(QString, content);
951 QFETCH(bool, priv);
952 QFETCH(bool, action);
953 QFETCH(bool, request);
954 QFETCH(uint, flags);
955
956 IrcConnection connection;
957 connection.setNickName("communi");
958 TestProtocol protocol(cap, &connection);
959 static_cast<FriendConnection*>(&connection)->setProtocol(&protocol);
960
961 IrcMessage* message = IrcMessage::fromData(data, &connection);
962 QCOMPARE(message->type(), IrcMessage::Private);
963 QCOMPARE(message->command(), QString("PRIVMSG"));
964 QCOMPARE(message->property("valid").toBool(), valid);
965 QCOMPARE(message->property("target").toString(), target);
966 QCOMPARE(message->property("content").toString(), content);
967 QCOMPARE(message->property("private").toBool(), priv);
968 QCOMPARE(message->property("action").toBool(), action);
969 QCOMPARE(message->property("request").toBool(), request);
970 QCOMPARE(message->property("flags").toUInt(), flags);
971
972 IrcPrivateMessage* privateMessage = qobject_cast<IrcPrivateMessage*>(message);
973 QVERIFY(privateMessage);
974 QCOMPARE(privateMessage->isValid(), valid);
975 QCOMPARE(privateMessage->target(), target);
976 QCOMPARE(privateMessage->content(), content);
977 QCOMPARE(privateMessage->isPrivate(), priv);
978 QCOMPARE(privateMessage->isAction(), action);
979 QCOMPARE(privateMessage->isRequest(), request);
980 QCOMPARE(static_cast<uint>(privateMessage->flags()), flags);
981 }
982
testQuitMessage_data()983 void tst_IrcMessage::testQuitMessage_data()
984 {
985 QTest::addColumn<bool>("valid");
986 QTest::addColumn<QByteArray>("data");
987 QTest::addColumn<QString>("reason");
988
989 QTest::newRow("no prefix") << true << QByteArray("QUIT :Gone to have lunch") << QString("Gone to have lunch");
990 QTest::newRow("empty prefix") << false << QByteArray(": QUIT :Gone to have lunch") << QString("Gone to have lunch");
991 QTest::newRow("no params") << true << QByteArray(":WiZ QUIT") << QString();
992 QTest::newRow("all ok") << true << QByteArray(":WiZ QUIT :Gone to have lunch") << QString("Gone to have lunch");
993 }
994
testQuitMessage()995 void tst_IrcMessage::testQuitMessage()
996 {
997 QFETCH(bool, valid);
998 QFETCH(QByteArray, data);
999 QFETCH(QString, reason);
1000
1001 IrcConnection connection;
1002 IrcMessage* message = IrcMessage::fromData(data, &connection);
1003 QCOMPARE(message->type(), IrcMessage::Quit);
1004 QCOMPARE(message->command(), QString("QUIT"));
1005 QCOMPARE(message->property("valid").toBool(), valid);
1006 QCOMPARE(message->property("reason").toString(), reason);
1007
1008 IrcQuitMessage* quitMessage = qobject_cast<IrcQuitMessage*>(message);
1009 QVERIFY(quitMessage);
1010 QCOMPARE(quitMessage->isValid(), valid);
1011 QCOMPARE(quitMessage->reason(), reason);
1012 }
1013
testTopicMessage_data()1014 void tst_IrcMessage::testTopicMessage_data()
1015 {
1016 QTest::addColumn<bool>("valid");
1017 QTest::addColumn<QByteArray>("data");
1018 QTest::addColumn<QString>("channel");
1019 QTest::addColumn<QString>("topic");
1020 QTest::addColumn<bool>("reply");
1021
1022 QTest::newRow("no prefix") << true << QByteArray("TOPIC #test") << QString("#test") << QString() << false;
1023 QTest::newRow("empty prefix") << false << QByteArray(": TOPIC #test") << QString("#test") << QString() << false;
1024 QTest::newRow("no params") << false << QByteArray(":WiZ TOPIC") << QString() << QString() << false;
1025 QTest::newRow("no topic") << true << QByteArray(":WiZ TOPIC #test") << QString("#test") << QString() << false;
1026 QTest::newRow("all ok") << true << QByteArray(":WiZ TOPIC #test :another topic") << QString("#test") << QString("another topic") << false;
1027 // TODO: QTest::newRow("numeric") << true << QByteArray(":server 332 user #test :foo bar") << QString("#test") << QString("foo bar") << true;
1028 }
1029
testTopicMessage()1030 void tst_IrcMessage::testTopicMessage()
1031 {
1032 QFETCH(bool, valid);
1033 QFETCH(QByteArray, data);
1034 QFETCH(QString, channel);
1035 QFETCH(QString, topic);
1036 QFETCH(bool, reply);
1037
1038 IrcConnection connection;
1039 IrcMessage* message = IrcMessage::fromData(data, &connection);
1040 QCOMPARE(message->type(), IrcMessage::Topic);
1041 QCOMPARE(message->command(), QString("TOPIC"));
1042 QCOMPARE(message->property("valid").toBool(), valid);
1043 QCOMPARE(message->property("channel").toString(), channel);
1044 QCOMPARE(message->property("topic").toString(), topic);
1045 QCOMPARE(message->property("reply").toBool(), reply);
1046
1047 IrcTopicMessage* topicMessage = qobject_cast<IrcTopicMessage*>(message);
1048 QVERIFY(topicMessage);
1049 QCOMPARE(topicMessage->isValid(), valid);
1050 QCOMPARE(topicMessage->channel(), channel);
1051 QCOMPARE(topicMessage->topic(), topic);
1052 QCOMPARE(topicMessage->isReply(), reply);
1053 }
1054
testWhoReplyMessage_data()1055 void tst_IrcMessage::testWhoReplyMessage_data()
1056 {
1057 QTest::addColumn<bool>("valid");
1058 QTest::addColumn<QString>("prefix");
1059 QTest::addColumn<QStringList>("params");
1060 QTest::addColumn<QString>("mask");
1061 QTest::addColumn<QString>("server");
1062 QTest::addColumn<bool>("away");
1063 QTest::addColumn<bool>("servOp");
1064 QTest::addColumn<QString>("realName");
1065
1066 QTest::newRow("normal") << true << "nick!ident@host"
1067 << (QStringList() << "#mask" << "irc.ser.ver" << "H@" << "real name")
1068 << "#mask" << "irc.ser.ver" << false << false << "real name";
1069
1070 QTest::newRow("away") << true << "nick!ident@host"
1071 << (QStringList() << "*" << "127.0.0.1" << "G@" << "real name")
1072 << "*" << "127.0.0.1" << true << false << "real name";
1073
1074 QTest::newRow("serv op") << true << "nick!ident@host"
1075 << (QStringList() << "*" << "127.0.0.1" << "H*@" << "real name")
1076 << "*" << "127.0.0.1" << false << true << "real name";
1077
1078 QTest::newRow("no name") << true << "nick!ident@host"
1079 << (QStringList() << "#mask" << "irc.ser.ver" << "H@" << "")
1080 << "#mask" << "irc.ser.ver" << false << false << "";
1081 }
1082
testWhoReplyMessage()1083 void tst_IrcMessage::testWhoReplyMessage()
1084 {
1085 QFETCH(bool, valid);
1086 QFETCH(QString, prefix);
1087 QFETCH(QStringList, params);
1088 QFETCH(QString, mask);
1089 QFETCH(QString, server);
1090 QFETCH(bool, away);
1091 QFETCH(bool, servOp);
1092 QFETCH(QString, realName);
1093
1094 IrcConnection connection;
1095 IrcWhoReplyMessage message(&connection);
1096 message.setPrefix(prefix);
1097 message.setParameters(params);
1098 QCOMPARE(message.isValid(), valid);
1099 QCOMPARE(message.type(), IrcMessage::WhoReply);
1100 // TODO: QCOMPARE(message.command(), QString::number(Irc::RPL_WHOREPLY));
1101 QCOMPARE(message.mask(), mask);
1102 QCOMPARE(message.server(), server);
1103 QCOMPARE(message.isAway(), away);
1104 QCOMPARE(message.isServOp(), servOp);
1105 QCOMPARE(message.realName(), realName);
1106
1107 QCOMPARE(message.property("valid").toBool(), valid);
1108 QCOMPARE(message.property("mask").toString(), mask);
1109 QCOMPARE(message.property("server").toString(), server);
1110 QCOMPARE(message.property("away").toBool(), away);
1111 QCOMPARE(message.property("servOp").toBool(), servOp);
1112 QCOMPARE(message.property("realName").toString(), realName);
1113 }
1114
testClone()1115 void tst_IrcMessage::testClone()
1116 {
1117 IrcConnection connection;
1118 IrcMessage* pm = IrcMessage::fromData("@a=b;c=d :nick!ident@host PRIVMSG me :hello", &connection);
1119 QVERIFY(pm);
1120 IrcMessage* clone = pm->clone(this);
1121 QVERIFY(clone);
1122 QVERIFY(clone->isValid());
1123 QCOMPARE(clone->parent(), this);
1124 QCOMPARE(clone->connection(), &connection);
1125 QCOMPARE(clone->type(), pm->type());
1126 QCOMPARE(clone->flags(), pm->flags());
1127 QCOMPARE(clone->tags(), pm->tags());
1128 QCOMPARE(clone->prefix(), pm->prefix());
1129 QCOMPARE(clone->nick(), pm->nick());
1130 QCOMPARE(clone->ident(), pm->ident());
1131 QCOMPARE(clone->host(), pm->host());
1132 QCOMPARE(clone->command(), pm->command());
1133 QCOMPARE(clone->parameters(), pm->parameters());
1134 QCOMPARE(clone->timeStamp(), pm->timeStamp());
1135 QCOMPARE(clone->account(), pm->account());
1136 }
1137
testNullConnection()1138 void tst_IrcMessage::testNullConnection()
1139 {
1140 IrcMessage* pm = IrcMessage::fromData(":nick!ident@host PRIVMSG me :hello", nullptr);
1141 QCOMPARE(pm->type(), IrcMessage::Private);
1142 QCOMPARE(pm->property("target").toString(), QString("me"));
1143 QVERIFY(pm->property("statusPrefix").toString().isEmpty());
1144 QVERIFY(!pm->property("private").toBool());
1145 QCOMPARE(pm->flags(), IrcMessage::None);
1146 delete pm;
1147
1148 IrcMessage* nm = IrcMessage::fromData(":nick!ident@host NOTICE me :hello", nullptr);
1149 QCOMPARE(nm->type(), IrcMessage::Notice);
1150 QCOMPARE(nm->property("target").toString(), QString("me"));
1151 QVERIFY(nm->property("statusPrefix").toString().isEmpty());
1152 QVERIFY(!nm->property("private").toBool());
1153 QCOMPARE(nm->flags(), IrcMessage::None);
1154 delete nm;
1155 }
1156
testDebug()1157 void tst_IrcMessage::testDebug()
1158 {
1159 QString str;
1160 QDebug dbg(&str);
1161
1162 dbg << static_cast<IrcMessage*>(nullptr);
1163 QCOMPARE(str.trimmed(), QString::fromLatin1("IrcMessage(0x0)"));
1164 str.clear();
1165
1166 IrcMessage message(nullptr);
1167 dbg << &message;
1168 QVERIFY(QRegularExpression("IrcMessage\\(0x[0-9A-Fa-f]+, flags=\\(None\\)\\) ").match(str).hasMatch());
1169 str.clear();
1170
1171 message.setObjectName("foo");
1172 dbg << &message;
1173 QVERIFY(QRegularExpression("IrcMessage\\(0x[0-9A-Fa-f]+, name=foo, flags=\\(None\\)\\) ").match(str).hasMatch());
1174 str.clear();
1175
1176 message.setPrefix("nick!ident@host");
1177 dbg << &message;
1178 QVERIFY(QRegularExpression("IrcMessage\\(0x[0-9A-Fa-f]+, name=foo, flags=\\(None\\), prefix=nick!ident@host\\) ").match(str).hasMatch());
1179 str.clear();
1180
1181 message.setCommand("COMMAND");
1182 dbg << &message;
1183 QVERIFY(QRegularExpression("IrcMessage\\(0x[0-9A-Fa-f]+, name=foo, flags=\\(None\\), prefix=nick!ident@host, command=COMMAND\\) ").match(str).hasMatch());
1184 str.clear();
1185
1186 message.setFlags(IrcMessage::Own | IrcMessage::Playback | IrcMessage::Implicit);
1187 dbg << &message;
1188 QVERIFY(QRegularExpression("IrcMessage\\(0x[0-9A-Fa-f]+, name=foo, flags=\\(Own\\|Playback\\|Implicit\\), prefix=nick!ident@host, command=COMMAND\\) ").match(str).hasMatch());
1189 str.clear();
1190
1191 dbg << IrcMessage::None;
1192 QCOMPARE(str.trimmed(), QString::fromLatin1("None"));
1193 str.clear();
1194
1195 dbg << IrcMessage::Join;
1196 QCOMPARE(str.trimmed(), QString::fromLatin1("Join"));
1197 str.clear();
1198
1199 dbg << IrcModeMessage::Channel;
1200 QCOMPARE(str.trimmed(), QString::fromLatin1("Channel"));
1201 str.clear();
1202 }
1203
1204 QTEST_MAIN(tst_IrcMessage)
1205
1206 #include "tst_ircmessage.moc"
1207