File indexing completed on 2024-05-12 05:40:52
0001 /*************************************************************************** 0002 * Copyright (C) 2011 by Renaud Guezennec * 0003 * http://renaudguezennec.homelinux.org/accueil,3.html * 0004 * * 0005 * Rolisteam is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 0021 #include <QtCore/QCoreApplication> 0022 #include <QtCore/QString> 0023 #include <QtTest/QtTest> 0024 0025 #include "data/character.h" 0026 #include "network/ipbanaccepter.h" 0027 #include "network/iprangeaccepter.h" 0028 #include "network/messagedispatcher.h" 0029 #include "network/networkmessagewriter.h" 0030 #include "network/passwordaccepter.h" 0031 #include "network/timeaccepter.h" 0032 #include "worker/messagehelper.h" 0033 #include "worker/playermessagehelper.h" 0034 0035 #include <helper.h> 0036 0037 class TestNetwork : public QObject 0038 { 0039 Q_OBJECT 0040 0041 public: 0042 TestNetwork(); 0043 0044 private slots: 0045 void initTestCase(); 0046 void cleanupTestCase(); 0047 void init(); 0048 void cleanup(); 0049 void writeTest(); 0050 void messageRecipiantTest(); 0051 void ipBanAccepterTest(); 0052 void ipBanAccepterTest_data(); 0053 void passwordAccepterTest(); 0054 void passwordAccepterTest_data(); 0055 void ipRangeAccepterTest(); 0056 void ipRangeAccepterTest_data(); 0057 void timeAccepterTest(); 0058 void timeAccepterTest_data(); 0059 0060 void messageDispatcherTest(); 0061 0062 void messageHeaderTest(); 0063 void messageHeaderTest_data(); 0064 0065 void messageWriterTest(); 0066 void playerMessageHelper(); 0067 0068 void messageHelperTest(); 0069 0070 private: 0071 std::unique_ptr<NetworkMessageWriter> m_writer; 0072 std::unique_ptr<IpBanAccepter> m_ipBanAccepter; 0073 std::unique_ptr<PasswordAccepter> m_passwordAccepter; 0074 std::unique_ptr<IpRangeAccepter> m_ipRangeAccepter; 0075 std::unique_ptr<TimeAccepter> m_timeAccepter; 0076 }; 0077 0078 Q_DECLARE_METATYPE(PasswordAccepter::Level) 0079 0080 TestNetwork::TestNetwork() {} 0081 0082 void TestNetwork::initTestCase() {} 0083 0084 void TestNetwork::cleanupTestCase() {} 0085 0086 void TestNetwork::init() 0087 { 0088 m_writer.reset(new NetworkMessageWriter(NetMsg::MediaCategory, NetMsg::AddMedia)); 0089 m_ipBanAccepter.reset(new IpBanAccepter()); 0090 m_passwordAccepter.reset(new PasswordAccepter()); 0091 m_ipRangeAccepter.reset(new IpRangeAccepter()); 0092 m_timeAccepter.reset(new TimeAccepter()); 0093 } 0094 void TestNetwork::writeTest() 0095 { 0096 for(quint8 i= 0; i < 255; ++i) 0097 { 0098 m_writer->uint8(i); 0099 QCOMPARE(m_writer->getDataSize(), (1 + i) * sizeof(quint8) + 1); //+sizeof(NetworkMessageHeader) 0100 } 0101 } 0102 /* 0103 void TestNetwork::writeAndReadTest() 0104 { 0105 0106 } 0107 0108 void TestNetwork::writeAndReadTest_data() 0109 { 0110 QTest::addColumn<QString>("currentIp"); 0111 QTest::addColumn<QStringList>("ipBan"); 0112 }*/ 0113 0114 void TestNetwork::cleanup() {} 0115 0116 void TestNetwork::messageRecipiantTest() 0117 { 0118 QStringList list= {"client1", "client2"}; 0119 QCOMPARE(m_writer->getRecipientMode(), NetworkMessage::All); 0120 0121 m_writer->setRecipientList(list, NetworkMessage::OneOrMany); 0122 0123 QCOMPARE(m_writer->getRecipientMode(), NetworkMessage::OneOrMany); 0124 } 0125 0126 void TestNetwork::ipBanAccepterTest() 0127 { 0128 QFETCH(QString, currentIp); 0129 QFETCH(QStringList, ipBan); 0130 QFETCH(bool, expected); 0131 0132 QMap<QString, QVariant> data= {{"currentIp", currentIp}, {"IpBan", ipBan}}; 0133 0134 QCOMPARE(m_ipBanAccepter->runAccepter(data), expected); 0135 0136 data.remove("IpBan"); 0137 0138 QCOMPARE(m_ipBanAccepter->runAccepter(data), true); 0139 } 0140 0141 void TestNetwork::ipBanAccepterTest_data() 0142 { 0143 QTest::addColumn<QString>("currentIp"); 0144 QTest::addColumn<QStringList>("ipBan"); 0145 QTest::addColumn<bool>("expected"); 0146 0147 QTest::addRow("localhost") << "127.0.0.1" << QStringList() << true; 0148 QTest::addRow("ipv4 ban") << "192.168.0.25" << QStringList({"192.168.0.25"}) << false; 0149 QTest::addRow("ipv4") << "192.168.0.24" << QStringList() << true; 0150 QTest::addRow("ipv6") << "2001:0db8:85a3:0000:0000:8a2e:0370:7334" << QStringList() << true; 0151 QTest::addRow("ipv6 ban") << "2001:0db8:85a3:0000:0000:8a2e:0370:7334" 0152 << QStringList({"2001:0db8:85a3:0000:0000:8a2e:0370:7334"}) << false; 0153 QTest::addRow("any") << "2001:0db8:85a3:0000:0000:8a2e:0370:7334:192.168.0.27" << QStringList() << true; 0154 QTest::addRow("any ban v6") << "2001:0db8:85a3:0000:0000:8a2e:0370:7334:192.168.1.45" 0155 << QStringList({"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "192.168.1.44"}) << false; 0156 QTest::addRow("any ban v4") << "2001:0db8:85a3:0000:0000:8a2e:0370:7334:192.168.1.45" 0157 << QStringList({"2001:0db8:85a3:0000:0000:4a2e:0370:7334", "192.168.1.45"}) << false; 0158 } // 2001:0db8:85a3:0000:0000:8a2e:0370:7334 0159 0160 void TestNetwork::passwordAccepterTest() 0161 { 0162 QFETCH(QString, currentPw); 0163 QFETCH(QString, expectedPw); 0164 QFETCH(PasswordAccepter::Level, level); 0165 QFETCH(bool, expected); 0166 0167 m_passwordAccepter.reset(new PasswordAccepter(level)); 0168 0169 QString key; 0170 0171 if(PasswordAccepter::Connection == level) 0172 { 0173 key= "ServerPassword"; 0174 } 0175 else if(PasswordAccepter::Admin == level) 0176 { 0177 key= "AdminPassword"; 0178 } 0179 else if(PasswordAccepter::Channel == level) 0180 { 0181 key= "ChannelPassword"; 0182 } 0183 0184 QVERIFY(!key.isEmpty()); 0185 0186 QMap<QString, QVariant> data= {{"userpassword", currentPw}, {key, expectedPw}}; 0187 0188 QCOMPARE(m_passwordAccepter->isValid(data), expected); 0189 } 0190 void TestNetwork::passwordAccepterTest_data() 0191 { 0192 QTest::addColumn<QString>("currentPw"); 0193 QTest::addColumn<QString>("expectedPw"); 0194 QTest::addColumn<PasswordAccepter::Level>("level"); 0195 QTest::addColumn<bool>("expected"); 0196 0197 QTest::addRow("server") << "tagada" 0198 << "tagada" << PasswordAccepter::Connection << true; 0199 QTest::addRow("server1") << "tagada" 0200 << "tagada1" << PasswordAccepter::Connection << false; 0201 QTest::addRow("server2") << "tagada" 0202 << "" << PasswordAccepter::Connection << false; 0203 0204 QTest::addRow("admin") << "tagada" 0205 << "tagada" << PasswordAccepter::Admin << true; 0206 QTest::addRow("admin1") << "tagada" 0207 << "tagada1" << PasswordAccepter::Admin << false; 0208 QTest::addRow("admin2") << "tagada" 0209 << "" << PasswordAccepter::Admin << false; 0210 0211 QTest::addRow("channel") << "tagada" 0212 << "tagada" << PasswordAccepter::Channel << true; 0213 QTest::addRow("channel1") << "tagada" 0214 << "tagada1" << PasswordAccepter::Channel << false; 0215 QTest::addRow("channel2") << "tagada" 0216 << "" << PasswordAccepter::Channel << false; 0217 } 0218 0219 void TestNetwork::ipRangeAccepterTest() 0220 { 0221 QFETCH(QString, currentIp); 0222 QFETCH(QString, range); 0223 QFETCH(bool, expected); 0224 0225 QMap<QString, QVariant> data= {{"currentIp", currentIp}, {"rangeIp", range}}; 0226 0227 if(range.isNull()) 0228 data.remove("IpRange"); 0229 0230 QCOMPARE(m_ipRangeAccepter->isValid(data), expected); 0231 } 0232 void TestNetwork::ipRangeAccepterTest_data() 0233 { 0234 QTest::addColumn<QString>("currentIp"); 0235 QTest::addColumn<QString>("range"); 0236 QTest::addColumn<bool>("expected"); 0237 0238 // QTest::addRow("range1") << "80.80.80.80" << "80.0.0.0.0/255.0.0.0" << true; 0239 QTest::addRow("range2") << "79.80.80.80" 0240 << "80.0.0.0.0/255.0.0.0" << false; 0241 0242 QTest::addRow("range3") << "192.168.1.15" 0243 << "192.168.1.0/24" << true; 0244 QTest::addRow("range3") << "192.168.0.15" 0245 << "192.168.1.0/24" << false; 0246 QTest::addRow("no ip") << "" 0247 << "192.168.1.0/24" << false; 0248 QTest::addRow("no range") << "192.168.0.15" << QString() << true; 0249 } 0250 void TestNetwork::timeAccepterTest() 0251 { 0252 bool expected= false; 0253 QFETCH(QString, start); 0254 QFETCH(QString, end); 0255 0256 QTime time= QTime::currentTime(); 0257 const QString format= QStringLiteral("hh:mm"); 0258 QTime startT= QTime::fromString(start, format); 0259 QTime endT= QTime::fromString(end, format); 0260 0261 if(start.isEmpty() && end.isEmpty()) 0262 expected= true; 0263 else if(time >= startT && time <= endT) 0264 expected= true; 0265 0266 QMap<QString, QVariant> data= {{"TimeStart", start}, {"TimeEnd", end}}; 0267 0268 QCOMPARE(m_timeAccepter->isValid(data), expected); 0269 } 0270 void TestNetwork::timeAccepterTest_data() 0271 { 0272 QTest::addColumn<QString>("start"); 0273 QTest::addColumn<QString>("end"); 0274 0275 int count= 0; 0276 for(int i= 0; i < 24; ++i) 0277 { 0278 QTest::addRow("time %d", ++count) << QStringLiteral("%1:00").arg(i, 2, 10, QLatin1Char('0')) 0279 << QStringLiteral("%1:30").arg(i, 2, 10, QLatin1Char('0')); 0280 0281 QTest::addRow("time %d", ++count) << QStringLiteral("%1:30").arg(i, 2, 10, QLatin1Char('0')) 0282 << QStringLiteral("%1:00").arg(i + 1, 2, 10, QLatin1Char('0')); 0283 } 0284 0285 QTest::addRow("time_null") << "" 0286 << ""; 0287 } 0288 0289 void TestNetwork::messageDispatcherTest() 0290 { 0291 MessageDispatcher dispatch; 0292 0293 dispatch.dispatchMessage(QByteArray(), nullptr, nullptr); 0294 dispatch.dispatchMessage(Helper::randomData(Helper::generate(100, 500)), nullptr, nullptr); 0295 0296 Channel channel; 0297 ServerConnection connect(nullptr); 0298 channel.addChild(&connect); 0299 dispatch.dispatchMessage(Helper::randomData(Helper::generate(100, 500)), &channel, nullptr); 0300 dispatch.dispatchMessage(Helper::randomData(Helper::generate(100, 500)), &channel, &connect); 0301 0302 /* 0303 * struct NETWORK_EXPORT NetworkMessageHeader 0304 { 0305 quint8 category; 0306 quint8 action; 0307 quint32 dataSize; 0308 }; 0309 */ 0310 } 0311 0312 void TestNetwork::messageWriterTest() 0313 { 0314 NetworkMessageWriter writer(NetMsg::Category::AdministrationCategory, NetMsg::Action::EndConnectionAction, 0315 NetworkMessage::All, 0); 0316 0317 QCOMPARE(writer.category(), NetMsg::Category::AdministrationCategory); 0318 QCOMPARE(writer.action(), NetMsg::Action::EndConnectionAction); 0319 0320 auto header= writer.buffer(); 0321 0322 QCOMPARE(header->category, NetMsg::Category::AdministrationCategory); 0323 QCOMPARE(header->action, NetMsg::Action::EndConnectionAction); 0324 QCOMPARE(writer.bufferSize(), 128); 0325 0326 writer.int16(18); 0327 writer.int32(200); 0328 0329 QCOMPARE(writer.currentPos(), sizeof(NetworkMessageHeader) + sizeof(qint32) + sizeof(qint16) + 1); 0330 QCOMPARE(writer.getRecipientList(), QStringList{}); 0331 0332 QPixmap pix; 0333 pix.loadFromData(Helper::imageData(false)); 0334 writer.pixmap(pix); 0335 } 0336 0337 void TestNetwork::messageHeaderTest() 0338 { 0339 QFETCH(quint8, cat); 0340 QFETCH(quint8, action); 0341 QFETCH(QString, resultCat); 0342 QFETCH(QString, resultAct); 0343 0344 NetworkMessageHeader header{cat, action, 0}; 0345 0346 QCOMPARE(MessageDispatcher::act2String(&header), resultAct); 0347 QCOMPARE(MessageDispatcher::cat2String(&header), resultCat); 0348 } 0349 0350 void TestNetwork::messageHeaderTest_data() 0351 { 0352 QTest::addColumn<quint8>("cat"); 0353 QTest::addColumn<quint8>("action"); 0354 QTest::addColumn<QString>("resultCat"); 0355 QTest::addColumn<QString>("resultAct"); 0356 0357 QStringList cats{"AdministrationCategory", 0358 "PlayerCategory", 0359 "CharacterPlayerCategory", 0360 "NPCCategory", 0361 "CharacterCategory", 0362 "DrawCategory", 0363 "MapCategory", 0364 "InstantMessageCategory", 0365 "MusicCategory", 0366 "SetupCategory", 0367 "CampaignCategory", 0368 "VMapCategory", 0369 "MediaCategory", 0370 "SharedNoteCategory", 0371 "WebPageCategory", 0372 "MindMapCategory"}; 0373 0374 QList<QStringList> actionPerCategorie; 0375 0376 actionPerCategorie.append({"EndConnectionAction", 0377 "Heartbeat", 0378 "ConnectionInfo", 0379 "Goodbye", 0380 "Kicked", 0381 "MoveChannel", 0382 "SetChannelList", 0383 "RenameChannel", 0384 "NeedPassword", 0385 "AuthentificationSucessed", 0386 "AuthentificationFail", 0387 "LockChannel", 0388 "UnlockChannel", 0389 "JoinChannel", 0390 "DeleteChannel", 0391 "AddChannel", 0392 "ChannelPassword", 0393 "ResetChannelPassword", 0394 "BanUser", 0395 "ClearTable", 0396 "AdminPassword", 0397 "AdminAuthSucessed", 0398 "AdminAuthFail", 0399 "MovedIntoChannel", 0400 "GMStatus", 0401 "ResetChannel"}); 0402 0403 actionPerCategorie.append({"PlayerConnectionAction", "DelPlayerAction", "ChangePlayerProperty"}); 0404 0405 actionPerCategorie.append({"AddPlayerCharacterAction", "DelPlayerCharacterAction", 0406 "ToggleViewPlayerCharacterAction", "ChangePlayerCharacterSizeAction", 0407 "ChangePlayerCharacterProperty"}); 0408 0409 actionPerCategorie.append(QStringList{"addNpc", "delNpc"}); 0410 0411 actionPerCategorie.append({"addCharacterList", "moveCharacter", "changeCharacterState", 0412 "changeCharacterOrientation", "showCharecterOrientation", "addCharacterSheet", 0413 "updateFieldCharacterSheet", "closeCharacterSheet"}); 0414 0415 actionPerCategorie.append({"penPainting", "linePainting", "emptyRectanglePainting", "filledRectanglePainting", 0416 "emptyEllipsePainting", "filledEllipsePainting", "textPainting", "handPainting"}); 0417 0418 actionPerCategorie.append({"AddEmptyMap", "LoadMap", "ImportMap", "CloseMap"}); 0419 0420 actionPerCategorie.append({ 0421 "InstantMessageAction", 0422 "AddChatroomAction", 0423 "RemoveChatroomAction", 0424 "UpdateChatAction", 0425 }); 0426 0427 actionPerCategorie.append({ 0428 "StopSong", 0429 "PlaySong", 0430 "PauseSong", 0431 "NewSong", 0432 "ChangePositionSong", 0433 }); 0434 actionPerCategorie.append(QStringList{"AddFeatureAction"}); 0435 actionPerCategorie.append({ 0436 "addDiceAlias", 0437 "moveDiceAlias", 0438 "removeDiceAlias", 0439 "addCharacterState", 0440 "moveCharacterState", 0441 "removeCharacterState", 0442 "DiceAliasModel", 0443 "CharactereStateModel", 0444 }); 0445 actionPerCategorie.append({ 0446 "AddItem", 0447 "DeleteItem", 0448 "UpdateItem", 0449 "AddPoint", 0450 "DeletePoint", 0451 "MovePoint", 0452 "SetParentItem", 0453 "CharcaterVisionChanged", 0454 "CharacterStateChanged", 0455 "CharacterChanged", 0456 "HighLightPosition", 0457 }); 0458 actionPerCategorie.append({ 0459 "AddMedia", 0460 "UpdateMediaProperty", 0461 "CloseMedia", 0462 "AddSubImage", 0463 "RemoveSubImage", 0464 }); 0465 actionPerCategorie.append({ 0466 "updateTextAndPermission", 0467 "updateText", 0468 "updatePermissionOneUser", 0469 }); 0470 actionPerCategorie.append(QStringList{"UpdateContent"}); 0471 actionPerCategorie.append( 0472 {"AddMessage", "RemoveMessage", "UpdateNode", "UpdatePackage", "UpdateLink", "UpdateMindMapPermission"}); 0473 0474 QCOMPARE(cats.size(), actionPerCategorie.size()); 0475 0476 for(quint8 i= 0; i < std::numeric_limits<quint8>::max(); ++i) 0477 { 0478 QString cat("UnknownCategory"); 0479 QStringList actionList; 0480 if(i < cats.size()) 0481 { 0482 actionList= actionPerCategorie[i]; 0483 cat= cats[i]; 0484 } 0485 0486 for(quint8 j= 0; j < std::numeric_limits<quint8>::max(); ++j) 0487 { 0488 QString act("Unknown Action"); 0489 if(j < actionList.size()) 0490 act= actionList[j]; 0491 0492 QTest::addRow("test: %d, %d", i, j) << i << j << cat << act; 0493 } 0494 } 0495 } 0496 0497 void TestNetwork::playerMessageHelper() 0498 { 0499 0500 // Player info 0501 Helper::TestMessageSender sender; 0502 NetworkMessage::setMessageSender(&sender); 0503 0504 Player player; 0505 player.setName(Helper::randomString()); 0506 player.setUuid(Helper::randomString()); 0507 0508 auto pw= Helper::randomData(); 0509 PlayerMessageHelper::sendOffConnectionInfo(&player, pw); 0510 0511 auto msgData= sender.messageData(); 0512 0513 PlayerMessageHelper::sendOffConnectionInfo(nullptr, pw); 0514 0515 { 0516 NetworkMessageReader reader; 0517 reader.setData(msgData); 0518 0519 QCOMPARE(reader.byteArray32(), pw); 0520 QCOMPARE(reader.string32(), player.name()); 0521 QCOMPARE(reader.string32(), player.uuid()); 0522 } 0523 0524 // Player info 0525 player.setGM(true); 0526 player.setAvatar(Helper::imageData(true)); 0527 player.setColor(Helper::randomColor()); 0528 PlayerMessageHelper::sendOffPlayerInformations(&player); 0529 0530 { 0531 NetworkMessageReader reader; 0532 reader.setData(sender.messageData()); 0533 0534 Player tempPlayer; 0535 0536 PlayerMessageHelper::readPlayer(reader, &tempPlayer); 0537 0538 QCOMPARE(player.isGM(), tempPlayer.isGM()); 0539 QCOMPARE(player.avatar(), tempPlayer.avatar()); 0540 QCOMPARE(player.getColor(), tempPlayer.getColor()); 0541 QCOMPARE(player.name(), tempPlayer.name()); 0542 QCOMPARE(player.uuid(), tempPlayer.uuid()); 0543 0544 PlayerMessageHelper::sendOffPlayerInformations(nullptr); 0545 } 0546 0547 { 0548 0549 auto character= new Character(); 0550 character->setUuid(Helper::randomString()); 0551 character->setName(Helper::randomString()); 0552 character->setColor(Helper::randomColor()); 0553 character->setLifeColor(Helper::randomColor()); 0554 character->setNpc(false); 0555 character->setAvatar(Helper::randomData()); 0556 0557 Player player; 0558 player.setName(Helper::randomString()); 0559 player.setUuid(Helper::randomString()); 0560 player.setGM(true); 0561 player.setAvatar(Helper::imageData(true)); 0562 player.setColor(Helper::randomColor()); 0563 player.addCharacter(character); 0564 0565 PlayerMessageHelper::sendOffPlayerInformations(&player); 0566 0567 NetworkMessageReader reader; 0568 reader.setData(sender.messageData()); 0569 Player tempPlayer; 0570 PlayerMessageHelper::readPlayer(reader, &tempPlayer); 0571 0572 QCOMPARE(player.isGM(), tempPlayer.isGM()); 0573 QCOMPARE(player.avatar(), tempPlayer.avatar()); 0574 QCOMPARE(player.getColor(), tempPlayer.getColor()); 0575 QCOMPARE(player.name(), tempPlayer.name()); 0576 QCOMPARE(player.uuid(), tempPlayer.uuid()); 0577 0578 QCOMPARE(tempPlayer.characterCount(), 1); 0579 auto tempCharacter= tempPlayer.characterById(character->uuid()); 0580 0581 QCOMPARE(character->name(), tempCharacter->name()); 0582 QCOMPARE(character->getLifeColor(), tempCharacter->getLifeColor()); 0583 QCOMPARE(character->getColor(), tempCharacter->getColor()); 0584 QCOMPARE(character->avatar(), tempCharacter->avatar()); 0585 QCOMPARE(character->uuid(), tempCharacter->uuid()); 0586 } 0587 } 0588 0589 void TestNetwork::messageHelperTest() 0590 { 0591 Helper::TestMessageSender sender; 0592 NetworkMessage::setMessageSender(&sender); 0593 0594 { 0595 MessageHelper::sendOffGoodBye(); 0596 0597 NetworkMessageReader reader; 0598 reader.setData(sender.messageData()); 0599 QCOMPARE(reader.action(), NetMsg::Goodbye); 0600 QCOMPARE(reader.category(), NetMsg::AdministrationCategory); 0601 } 0602 0603 { 0604 auto id= Helper::randomString(); 0605 MessageHelper::closeMedia(id, Core::ContentType::CHARACTERSHEET); 0606 0607 NetworkMessageReader reader; 0608 reader.setData(sender.messageData()); 0609 0610 QCOMPARE(reader.action(), NetMsg::CloseMedia); 0611 QCOMPARE(reader.category(), NetMsg::MediaCategory); 0612 0613 QCOMPARE(reader.uint8(), static_cast<int>(Core::ContentType::CHARACTERSHEET)); 0614 QCOMPARE(reader.string8(), id); 0615 } 0616 } 0617 0618 QTEST_MAIN(TestNetwork); 0619 0620 #include "tst_network.moc"