File indexing completed on 2024-06-09 04:57:48
0001 /* 0002 SPDX-FileCopyrightText: 2023-2024 Laurent Montel <montel.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "localmessagedatabasetest.h" 0008 #include "localdatabase/localmessagedatabase.h" 0009 #include "messages/message.h" 0010 0011 #include <QSqlRecord> 0012 #include <QSqlTableModel> 0013 #include <QStandardPaths> 0014 #include <QTest> 0015 0016 QTEST_GUILESS_MAIN(LocalMessageDatabaseTest) 0017 0018 static QString accountName() 0019 { 0020 return QStringLiteral("myAccount"); 0021 } 0022 static QString roomName() 0023 { 0024 return QStringLiteral("myRoom"); 0025 } 0026 static QString otherRoomName() 0027 { 0028 return QStringLiteral("otherRoom"); 0029 } 0030 static QString existingRoomName() 0031 { 0032 return QStringLiteral("existingRoom"); 0033 } 0034 enum class Fields { 0035 MessageId, 0036 TimeStamp, 0037 Json, 0038 }; // in the same order as the table 0039 0040 void LocalMessageDatabaseTest::initTestCase() 0041 { 0042 QStandardPaths::setTestModeEnabled(true); 0043 0044 // Clean up after previous runs 0045 LocalMessageDatabase logger; 0046 QFile::remove(logger.dbFileName(accountName(), roomName())); 0047 QFile::remove(logger.dbFileName(accountName(), otherRoomName())); 0048 QFile::remove(logger.dbFileName(accountName(), existingRoomName())); 0049 } 0050 0051 void LocalMessageDatabaseTest::shouldStoreMessages() 0052 { 0053 // GIVEN 0054 LocalMessageDatabase logger; 0055 0056 Message message1; 0057 message1.setText(QString::fromUtf8("Message text: €1")); 0058 message1.setUsername(QString::fromUtf8("Hervé")); 0059 message1.setTimeStamp(QDateTime(QDate(2021, 6, 7), QTime(23, 50, 50)).toMSecsSinceEpoch()); 0060 message1.setMessageId(QStringLiteral("msg-1")); 0061 logger.addMessage(accountName(), roomName(), message1); 0062 0063 message1.setText(QString::fromUtf8("Message text: €2")); 0064 message1.setTimeStamp(QDateTime(QDate(2021, 6, 7), QTime(23, 50, 55)).toMSecsSinceEpoch()); 0065 logger.addMessage(accountName(), roomName(), message1); // update an existing message 5s later 0066 0067 Message message2; 0068 message2.setText(QString::fromUtf8("Message text: ßĐ")); 0069 message2.setUsername(QString::fromUtf8("Joe")); 0070 message2.setTimeStamp(QDateTime(QDate(2022, 6, 7), QTime(23, 40, 50)).toMSecsSinceEpoch()); // earlier 0071 message2.setMessageId(QStringLiteral("msg-2")); 0072 logger.addMessage(accountName(), roomName(), message2); 0073 0074 Message messageOtherRoom; 0075 messageOtherRoom.setText(QString::fromUtf8("Message other room")); 0076 messageOtherRoom.setUsername(QString::fromUtf8("Joe")); 0077 messageOtherRoom.setTimeStamp(QDateTime(QDate(2022, 6, 7), QTime(23, 30, 50)).toMSecsSinceEpoch()); 0078 messageOtherRoom.setMessageId(QStringLiteral("msg-other-1")); 0079 logger.addMessage(accountName(), otherRoomName(), messageOtherRoom); 0080 0081 // WHEN 0082 auto tableModel = logger.createMessageModel(accountName(), roomName()); 0083 0084 // THEN 0085 QVERIFY(tableModel); 0086 QCOMPARE(tableModel->rowCount(), 2); 0087 const QSqlRecord record0 = tableModel->record(0); 0088 QCOMPARE(record0.value(int(Fields::Json)).toByteArray(), Message::serialize(message1, false)); 0089 QCOMPARE(record0.value(int(Fields::TimeStamp)).toULongLong(), message1.timeStamp()); 0090 const QSqlRecord record1 = tableModel->record(1); 0091 QCOMPARE(record1.value(int(Fields::Json)).toByteArray(), Message::serialize(message2, false)); 0092 QCOMPARE(record1.value(int(Fields::TimeStamp)).toULongLong(), message2.timeStamp()); 0093 } 0094 0095 void LocalMessageDatabaseTest::shouldLoadExistingDb() // this test depends on shouldStoreMessages() 0096 { 0097 // GIVEN 0098 LocalMessageDatabase logger; 0099 // Copy an existing db under a new room name, so that there's not yet a QSqlDatabase for it 0100 QSqlDatabase::database(accountName() + QLatin1Char('-') + otherRoomName()).close(); 0101 const QString srcDb = logger.dbFileName(accountName(), otherRoomName()); 0102 const QString destDb = logger.dbFileName(accountName(), existingRoomName()); 0103 QVERIFY(QFileInfo::exists(srcDb)); 0104 QVERIFY(!QFileInfo::exists(destDb)); 0105 QVERIFY(QFile::copy(srcDb, destDb)); 0106 0107 // WHEN 0108 auto tableModel = logger.createMessageModel(accountName(), existingRoomName()); 0109 qDebug() << " accountName() " << accountName() << " existingRoomName() " << existingRoomName(); 0110 0111 // THEN 0112 QVERIFY(tableModel); 0113 QCOMPARE(tableModel->rowCount(), 0); 0114 } 0115 0116 void LocalMessageDatabaseTest::shouldDeleteMessages() // this test depends on shouldStoreMessages() 0117 { 0118 // GIVEN 0119 LocalMessageDatabase logger; 0120 const QString messageId = (QStringLiteral("msg-other-1")); 0121 0122 // WHEN 0123 logger.deleteMessage(accountName(), otherRoomName(), messageId); 0124 0125 // THEN 0126 auto tableModel = logger.createMessageModel(accountName(), otherRoomName()); 0127 QVERIFY(tableModel); 0128 QCOMPARE(tableModel->rowCount(), 0); 0129 } 0130 0131 void LocalMessageDatabaseTest::shouldReturnNullIfDoesNotExist() 0132 { 0133 // GIVEN 0134 LocalMessageDatabase logger; 0135 // WHEN 0136 auto tableModel = logger.createMessageModel(accountName(), QStringLiteral("does not exist")); 0137 // THEN 0138 QVERIFY(!tableModel); 0139 } 0140 0141 void LocalMessageDatabaseTest::shouldExtractMessages() 0142 { 0143 // GIVEN 0144 LocalMessageDatabase logger; 0145 for (int i = 0; i < 20; ++i) { 0146 Message message1; 0147 message1.setText(QString::fromUtf8("Message text: %1").arg(i)); 0148 message1.setUsername(QString::fromUtf8("Hervé %1").arg(i)); 0149 message1.setTimeStamp(QDateTime(QDate(2021, 6, 7), QTime(23, 50 + i, 50)).toMSecsSinceEpoch()); 0150 message1.setMessageId(QStringLiteral("msg-%1").arg(i)); 0151 logger.addMessage(accountName(), roomName(), message1); 0152 } 0153 // WHEN 0154 auto tableModel = logger.createMessageModel(accountName(), roomName()); 0155 // THEN 0156 QVERIFY(tableModel); 0157 QCOMPARE(tableModel->rowCount(), 20); 0158 } 0159 0160 void LocalMessageDatabaseTest::shouldExtractSpecificNumberOfMessages_data() 0161 { 0162 QTest::addColumn<qint64>("startId"); 0163 QTest::addColumn<qint64>("endId"); 0164 QTest::addColumn<qint64>("numberElement"); 0165 QTest::addColumn<qint64>("result"); 0166 0167 QTest::addRow("test1") << static_cast<qint64>(-1) << static_cast<qint64>(-1) << static_cast<qint64>(5) << static_cast<qint64>(5); 0168 0169 QTest::addRow("ask-more-elements") << static_cast<qint64>(-1) << static_cast<qint64>(-1) << static_cast<qint64>(25) << static_cast<qint64>(20); 0170 QTest::addRow("ask-equal-elements") << static_cast<qint64>(-1) << static_cast<qint64>(-1) << static_cast<qint64>(20) << static_cast<qint64>(20); 0171 QTest::addRow("ask-no-element") << static_cast<qint64>(-1) << static_cast<qint64>(-1) << static_cast<qint64>(0) << static_cast<qint64>(0); 0172 0173 // Time stand start 0174 QTest::addRow("timestand-start1") << static_cast<qint64>(1623100790000) << static_cast<qint64>(-1) << static_cast<qint64>(0) << static_cast<qint64>(0); 0175 QTest::addRow("timestand-start2") << static_cast<qint64>(1623100790000) << static_cast<qint64>(-1) << static_cast<qint64>(1) << static_cast<qint64>(1); 0176 QTest::addRow("timestand-start3") << static_cast<qint64>(1623100790000) << static_cast<qint64>(-1) << static_cast<qint64>(2) << static_cast<qint64>(2); 0177 QTest::addRow("timestand-start4") << static_cast<qint64>(1623100790000) << static_cast<qint64>(-1) << static_cast<qint64>(10) << static_cast<qint64>(2); 0178 QTest::addRow("timestand-start5") << static_cast<qint64>(1623100790000) << static_cast<qint64>(-1) << (qint64)3 << static_cast<qint64>(2); 0179 0180 // Start 1623099710000 end 1623100850000 0181 QTest::addRow("timestand-start1-end1") << static_cast<qint64>(1623099710000) << static_cast<qint64>(1623099710000) << static_cast<qint64>(5) 0182 << static_cast<qint64>(1); 0183 QTest::addRow("timestand-start1-end2") << static_cast<qint64>(1623099710000) << static_cast<qint64>(1623100850000) << static_cast<qint64>(30) 0184 << static_cast<qint64>(20); 0185 0186 // End 0187 QTest::addRow("timestand-end1") << static_cast<qint64>(-1) << static_cast<qint64>(1623099710000) << static_cast<qint64>(5) << static_cast<qint64>(1); 0188 QTest::addRow("timestand-end3") << static_cast<qint64>(-1) << (qint64)(QDateTime(QDate(2021, 6, 7), QTime(23, 1 + 3, 50)).toMSecsSinceEpoch()) 0189 << static_cast<qint64>(5) << (qint64)4; 0190 } 0191 0192 void LocalMessageDatabaseTest::shouldExtractSpecificNumberOfMessages() 0193 { 0194 QFETCH(qint64, startId); 0195 QFETCH(qint64, endId); 0196 QFETCH(qint64, numberElement); 0197 QFETCH(qint64, result); 0198 0199 // GIVEN 0200 LocalMessageDatabase logger; 0201 for (int i = 0; i < 20; ++i) { 0202 Message message1; 0203 message1.setText(QString::fromUtf8("Message text: %1").arg(i)); 0204 message1.setUsername(QString::fromUtf8("Hervé %1").arg(i)); 0205 message1.setTimeStamp(QDateTime(QDate(2021, 6, 7), QTime(23, 1 + i, 50)).toMSecsSinceEpoch()); 0206 message1.setMessageId(QStringLiteral("msg-%1").arg(i)); 0207 logger.addMessage(accountName(), roomName(), message1); 0208 } 0209 // WHEN 0210 const QVector<Message> messages = logger.loadMessages(accountName(), roomName(), startId, endId, numberElement); 0211 0212 // THEN 0213 QCOMPARE(messages.count(), result); 0214 } 0215 0216 void LocalMessageDatabaseTest::shouldGenerateQuery() 0217 { 0218 QFETCH(qint64, startId); 0219 QFETCH(qint64, endId); 0220 QFETCH(qint64, numberElement); 0221 QFETCH(QString, result); 0222 0223 // GIVEN 0224 // WHEN 0225 const QString queryStr = LocalMessageDatabase::generateQueryStr(startId, endId, numberElement); 0226 0227 // THEN 0228 QCOMPARE(queryStr, result); 0229 } 0230 0231 void LocalMessageDatabaseTest::shouldGenerateQuery_data() 0232 { 0233 QTest::addColumn<qint64>("startId"); 0234 QTest::addColumn<qint64>("endId"); 0235 QTest::addColumn<qint64>("numberElement"); 0236 QTest::addColumn<QString>("result"); 0237 0238 QTest::addRow("test1") << static_cast<qint64>(-1) << static_cast<qint64>(-1) << static_cast<qint64>(5) 0239 << QStringLiteral("SELECT * FROM MESSAGES ORDER BY timestamp DESC LIMIT :limit"); 0240 QTest::addRow("test2") << static_cast<qint64>(-1) << static_cast<qint64>(-1) << static_cast<qint64>(-1) 0241 << QStringLiteral("SELECT * FROM MESSAGES ORDER BY timestamp DESC"); 0242 QTest::addRow("test3") << static_cast<qint64>(5) << static_cast<qint64>(-1) << static_cast<qint64>(-1) 0243 << QStringLiteral("SELECT * FROM MESSAGES WHERE timestamp >= :startId ORDER BY timestamp DESC"); 0244 QTest::addRow("test4") << static_cast<qint64>(-1) << static_cast<qint64>(5) << static_cast<qint64>(-1) 0245 << QStringLiteral("SELECT * FROM MESSAGES WHERE timestamp <= :endId ORDER BY timestamp DESC"); 0246 QTest::addRow("test5") << static_cast<qint64>(5) << static_cast<qint64>(5) << static_cast<qint64>(-1) 0247 << QStringLiteral("SELECT * FROM MESSAGES WHERE timestamp >= :startId AND timestamp <= :endId ORDER BY timestamp DESC"); 0248 QTest::addRow("test6") << static_cast<qint64>(5) << static_cast<qint64>(5) << static_cast<qint64>(30) 0249 << QStringLiteral("SELECT * FROM MESSAGES WHERE timestamp >= :startId AND timestamp <= :endId ORDER BY timestamp DESC LIMIT :limit"); 0250 } 0251 0252 void LocalMessageDatabaseTest::shouldVerifyDbFileName() 0253 { 0254 LocalMessageDatabase accountDataBase; 0255 QCOMPARE(accountDataBase.dbFileName(accountName()), 0256 QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QStringLiteral("/database/messages/myAccount/myAccount.sqlite")); 0257 } 0258 0259 #include "moc_localmessagedatabasetest.cpp"