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"