#include #include #include #include #include #include #include "service/tcpserver.h" #include "service/tcpclient.h" #include "service/server.h" #include "service/service.h" #include "items/item.h" class TestTcp : public QObject { Q_OBJECT private slots: void initTestCase() { // Setup for all tests } void testTcpServerCreation() { TcpServer server; // Server should be created successfully QVERIFY(true); } void testTcpServerLaunch() { TcpServer server; // Launch server on any address, port 0 means dynamic port bool result = server.launch(QHostAddress::Any, 0); QVERIFY(result); // Server should be listening after launch QVERIFY(server.isListening()); } void testTcpServerLaunchSpecificPort() { TcpServer server; // Try to launch on a specific port bool result = server.launch(QHostAddress::LocalHost, 0); QVERIFY(result); // Server should be listening QVERIFY(server.isListening()); } void testTcpClientCreation() { TcpClient client; // Client should be created successfully QVERIFY(true); } void testTcpProtocolMessageFormat() { // Test the protocol message format: "MSG JSON LEN \n" QJsonObject json; json["MessageType"] = "TestMessage"; json["Data"] = QJsonArray(); QByteArray jsonData = QJsonDocument(json).toJson(); QString message = QString("MSG JSON LEN %1\n").arg(jsonData.size()) + QString::fromUtf8(jsonData); // Verify message format QVERIFY(message.startsWith("MSG JSON LEN ")); QVERIFY(message.contains("\n")); // Parse the message size QStringList parts = message.split("\n"); QVERIFY(parts.size() >= 1); QString sizeStr = parts[0].mid(13); // Skip "MSG JSON LEN " bool ok; quint64 size = sizeStr.toUInt(&ok); QVERIFY(ok); QVERIFY(size == jsonData.size()); } void testTcpProtocolParseCommand() { // Test parsing a command from the protocol QByteArray command = "MSG JSON LEN 123\n"; QVERIFY(command.startsWith("MSG JSON LEN ")); QByteArray sizeStr = command.mid(13); sizeStr.chop(1); // Remove newline bool ok; quint64 size = sizeStr.toLongLong(&ok); QVERIFY(ok); QVERIFY(size == 123); } void testTcpServerSendJson() { // Start server TcpServer server; bool serverResult = server.launch(QHostAddress::LocalHost, 0); QVERIFY(serverResult); // Connect a client to trigger client list QTcpSocket clientSocket; clientSocket.connectToHost(QHostAddress::LocalHost, server.getServerPort()); QVERIFY(clientSocket.waitForConnected(1000)); // Give server time to accept connection QTest::qWait(200); // Send JSON from server QJsonObject json; json["MessageType"] = "TestMessage"; json["Data"] = QJsonArray(); server.sendJson(json); // Give more time for data to be sent QTest::qWait(200); // Client should receive data (or at least the connection should work) // Note: This may fail due to timing in test environment QVERIFY(clientSocket.state() == QTcpSocket::ConnectedState); // Cleanup clientSocket.close(); } void testTcpServerProcessIncomingJson() { // Start server TcpServer server; bool serverResult = server.launch(QHostAddress::LocalHost, 0); QVERIFY(serverResult); // Connect client QTcpSocket clientSocket; clientSocket.connectToHost(QHostAddress::LocalHost, server.getServerPort()); QVERIFY(clientSocket.waitForConnected(1000)); // Give server time to accept connection QTest::qWait(100); // Send a message that the server can process QJsonObject json; json["MessageType"] = "GetItems"; json["Data"] = QJsonArray(); QByteArray jsonData = QJsonDocument(json).toJson(); QString message = QString("MSG JSON LEN %1\n").arg(jsonData.size()) + QString::fromUtf8(jsonData); clientSocket.write(message.toUtf8()); clientSocket.flush(); // Give server time to process QTest::qWait(100); // Cleanup clientSocket.close(); } void testTcpServerMultipleClients() { // Start server TcpServer server; bool serverResult = server.launch(QHostAddress::LocalHost, 0); QVERIFY(serverResult); // Connect multiple clients QTcpSocket client1; client1.connectToHost(QHostAddress::LocalHost, server.getServerPort()); QVERIFY(client1.waitForConnected(1000)); QTcpSocket client2; client2.connectToHost(QHostAddress::LocalHost, server.getServerPort()); QVERIFY(client2.waitForConnected(1000)); // Give server time to accept connections QTest::qWait(200); // Send message to all clients QJsonObject json; json["MessageType"] = "TestMessage"; json["Data"] = QJsonArray(); server.sendJson(json); // Give time for data to be sent QTest::qWait(200); // Both clients should be connected (timing may affect actual data receipt) QVERIFY(client1.state() == QTcpSocket::ConnectedState); QVERIFY(client2.state() == QTcpSocket::ConnectedState); // Cleanup client1.close(); client2.close(); } void testItemUpdateMessageFormat() { // Test creating an item update message format Item item(1, "test_item", 1); QJsonObject itemJson; item.store(itemJson); QJsonArray items; items.append(itemJson); // Manually create the message (since createMessage is protected) QJsonObject message; message["MessageType"] = "ItemUpdate"; message["Data"] = items; message["FullList"] = false; QVERIFY(message["MessageType"].toString() == "ItemUpdate"); QVERIFY(message["Data"].toArray().size() == 1); QVERIFY(message["FullList"].toBool() == false); } void testSensorUpdateMessageFormat() { // Test creating a sensor update message format Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.0, "temp_sensor"); QJsonObject sensorJson; sensor.store(sensorJson); QJsonArray sensors; sensors.append(sensorJson); // Manually create the message (since createMessage is protected) QJsonObject message; message["MessageType"] = "SensorUpdate"; message["Data"] = sensors; QVERIFY(message["MessageType"].toString() == "SensorUpdate"); QVERIFY(message["Data"].toArray().size() == 1); } void testTcpClientSocketState() { // Test that TcpClient creates a socket TcpClient client; // The client should have a valid socket (internal implementation detail) // We can verify the client was created successfully QVERIFY(true); } void testTcpServerClientConnection() { // Start server TcpServer server; bool serverResult = server.launch(QHostAddress::LocalHost, 0); QVERIFY(serverResult); // Connect a client QTcpSocket clientSocket; clientSocket.connectToHost(QHostAddress::LocalHost, server.getServerPort()); bool waitResult = clientSocket.waitForConnected(1000); QVERIFY(waitResult); // Verify connection state QVERIFY(clientSocket.state() == QTcpSocket::ConnectedState); // Cleanup clientSocket.close(); } void testTcpServerDisconnection() { // Start server TcpServer server; bool serverResult = server.launch(QHostAddress::LocalHost, 0); QVERIFY(serverResult); // Connect a client QTcpSocket* client = new QTcpSocket(); client->connectToHost(QHostAddress::LocalHost, server.getServerPort()); QVERIFY(client->waitForConnected(1000)); // Give server time to accept connection QTest::qWait(100); // Disconnect client client->disconnectFromHost(); QTest::qWait(100); // Cleanup delete client; } void testTcpProtocolLargeMessage() { // Test the protocol with a larger message QJsonObject json; json["MessageType"] = "TestMessage"; // Create a large data array QJsonArray data; for (int i = 0; i < 100; i++) { data.append(QJsonObject{{"id", i}, {"value", QString("item%1").arg(i)}}); } json["Data"] = data; QByteArray jsonData = QJsonDocument(json).toJson(); QString message = QString("MSG JSON LEN %1\n").arg(jsonData.size()) + QString::fromUtf8(jsonData); // Verify message format QVERIFY(message.startsWith("MSG JSON LEN ")); // Parse the message size QStringList parts = message.split("\n"); QString sizeStr = parts[0].mid(13); bool ok; quint64 size = sizeStr.toUInt(&ok); QVERIFY(ok); QVERIFY(size == jsonData.size()); } void cleanupTestCase() { // Cleanup after all tests } }; QTEST_APPLESS_MAIN(TestTcp) #include "test_tcp.moc"