2019-05-26 03:16:56 +08:00
|
|
|
/*
|
|
|
|
Copyright © 2019 by The qTox Project Contributors
|
|
|
|
|
|
|
|
This file is part of qTox, a Qt-based graphical interface for Tox.
|
|
|
|
|
|
|
|
qTox is libre software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
qTox is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "src/core/core.h"
|
|
|
|
#include "src/model/friend.h"
|
2019-11-17 10:06:33 +08:00
|
|
|
#include "src/model/status.h"
|
2019-05-26 03:16:56 +08:00
|
|
|
#include "src/persistence/offlinemsgengine.h"
|
|
|
|
|
|
|
|
#include <QtTest/QtTest>
|
|
|
|
|
|
|
|
struct MockFriendMessageSender : public QObject, public ICoreFriendMessageSender
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
MockFriendMessageSender(Friend* f)
|
|
|
|
: f(f){};
|
|
|
|
bool sendAction(uint32_t friendId, const QString& action, ReceiptNum& receipt) override
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
bool sendMessage(uint32_t friendId, const QString& message, ReceiptNum& receipt) override
|
|
|
|
{
|
2019-11-17 10:06:33 +08:00
|
|
|
if (Status::isOnline(f->getStatus())) {
|
2019-05-26 03:16:56 +08:00
|
|
|
receipt.get() = receiptNum++;
|
|
|
|
if (!dropReceipts) {
|
|
|
|
msgs.push_back(message);
|
|
|
|
emit receiptReceived(receipt);
|
|
|
|
}
|
|
|
|
numMessagesSent++;
|
|
|
|
} else {
|
|
|
|
numMessagesFailed++;
|
|
|
|
}
|
2019-11-17 10:06:33 +08:00
|
|
|
return Status::isOnline(f->getStatus());
|
2019-05-26 03:16:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void receiptReceived(ReceiptNum receipt);
|
|
|
|
|
|
|
|
public:
|
|
|
|
Friend* f;
|
|
|
|
bool dropReceipts = false;
|
|
|
|
size_t numMessagesSent = 0;
|
|
|
|
size_t numMessagesFailed = 0;
|
|
|
|
int receiptNum = 0;
|
|
|
|
std::vector<QString> msgs;
|
|
|
|
};
|
|
|
|
|
|
|
|
class TestOfflineMsgEngine : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void testReceiptResolution();
|
|
|
|
void testOfflineFriend();
|
|
|
|
void testSentUnsentCoordination();
|
|
|
|
void testCallback();
|
|
|
|
};
|
|
|
|
|
|
|
|
class OfflineMsgEngineFixture
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
OfflineMsgEngineFixture()
|
|
|
|
: f(0, ToxPk(QByteArray(32, 0)))
|
|
|
|
, friendMessageSender(&f)
|
|
|
|
, offlineMsgEngine(&f, &friendMessageSender)
|
|
|
|
{
|
|
|
|
f.setStatus(Status::Status::Online);
|
|
|
|
QObject::connect(&friendMessageSender, &MockFriendMessageSender::receiptReceived,
|
|
|
|
&offlineMsgEngine, &OfflineMsgEngine::onReceiptReceived);
|
|
|
|
}
|
|
|
|
|
|
|
|
Friend f;
|
|
|
|
MockFriendMessageSender friendMessageSender;
|
|
|
|
OfflineMsgEngine offlineMsgEngine;
|
|
|
|
};
|
|
|
|
|
|
|
|
void completionFn() {}
|
|
|
|
|
|
|
|
void TestOfflineMsgEngine::testReceiptResolution()
|
|
|
|
{
|
|
|
|
OfflineMsgEngineFixture fixture;
|
|
|
|
|
|
|
|
Message msg{false, QString(), QDateTime()};
|
|
|
|
|
|
|
|
ReceiptNum receipt;
|
|
|
|
fixture.friendMessageSender.sendMessage(0, msg.content, receipt);
|
|
|
|
fixture.offlineMsgEngine.addSentMessage(receipt, msg, completionFn);
|
|
|
|
|
|
|
|
// We should have no offline messages to deliver if we resolved our receipt
|
|
|
|
// correctly
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
|
|
|
|
QVERIFY(fixture.friendMessageSender.numMessagesSent == 1);
|
|
|
|
|
|
|
|
// If we drop receipts we should keep trying to send messages every time we
|
|
|
|
// "deliverOfflineMsgs"
|
|
|
|
fixture.friendMessageSender.dropReceipts = true;
|
|
|
|
fixture.friendMessageSender.sendMessage(0, msg.content, receipt);
|
|
|
|
fixture.offlineMsgEngine.addSentMessage(receipt, msg, completionFn);
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
|
|
|
|
QVERIFY(fixture.friendMessageSender.numMessagesSent == 5);
|
|
|
|
|
|
|
|
// And once we stop dropping and try one more time we should run out of
|
|
|
|
// messages to send again
|
|
|
|
fixture.friendMessageSender.dropReceipts = false;
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
QVERIFY(fixture.friendMessageSender.numMessagesSent == 6);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestOfflineMsgEngine::testOfflineFriend()
|
|
|
|
{
|
|
|
|
OfflineMsgEngineFixture fixture;
|
|
|
|
|
|
|
|
Message msg{false, QString(), QDateTime()};
|
|
|
|
|
|
|
|
fixture.f.setStatus(Status::Status::Offline);
|
|
|
|
|
|
|
|
fixture.offlineMsgEngine.addUnsentMessage(msg, completionFn);
|
|
|
|
fixture.offlineMsgEngine.addUnsentMessage(msg, completionFn);
|
|
|
|
fixture.offlineMsgEngine.addUnsentMessage(msg, completionFn);
|
|
|
|
fixture.offlineMsgEngine.addUnsentMessage(msg, completionFn);
|
|
|
|
fixture.offlineMsgEngine.addUnsentMessage(msg, completionFn);
|
|
|
|
|
|
|
|
fixture.f.setStatus(Status::Status::Online);
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
|
|
|
|
|
|
|
|
QVERIFY(fixture.friendMessageSender.numMessagesFailed == 0);
|
|
|
|
QVERIFY(fixture.friendMessageSender.numMessagesSent == 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestOfflineMsgEngine::testSentUnsentCoordination()
|
|
|
|
{
|
|
|
|
OfflineMsgEngineFixture fixture;
|
|
|
|
Message msg{false, QString("a"), QDateTime()};
|
|
|
|
ReceiptNum receipt;
|
|
|
|
|
|
|
|
fixture.offlineMsgEngine.addUnsentMessage(msg, completionFn);
|
|
|
|
msg.content = "b";
|
|
|
|
fixture.friendMessageSender.dropReceipts = true;
|
|
|
|
fixture.friendMessageSender.sendMessage(0, msg.content, receipt);
|
|
|
|
fixture.friendMessageSender.dropReceipts = false;
|
|
|
|
fixture.offlineMsgEngine.addSentMessage(receipt, msg, completionFn);
|
|
|
|
msg.content = "c";
|
|
|
|
fixture.offlineMsgEngine.addUnsentMessage(msg, completionFn);
|
|
|
|
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
|
|
|
|
auto expectedResponseOrder = std::vector<QString>{"a", "b", "c"};
|
|
|
|
QVERIFY(fixture.friendMessageSender.msgs == expectedResponseOrder);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestOfflineMsgEngine::testCallback()
|
|
|
|
{
|
|
|
|
OfflineMsgEngineFixture fixture;
|
|
|
|
|
|
|
|
size_t numCallbacks = 0;
|
|
|
|
auto callback = [&numCallbacks] { numCallbacks++; };
|
|
|
|
Message msg{false, QString(), QDateTime()};
|
|
|
|
ReceiptNum receipt;
|
|
|
|
|
|
|
|
fixture.friendMessageSender.sendMessage(0, msg.content, receipt);
|
|
|
|
fixture.offlineMsgEngine.addSentMessage(receipt, msg, callback);
|
|
|
|
fixture.offlineMsgEngine.addUnsentMessage(msg, callback);
|
|
|
|
|
|
|
|
fixture.offlineMsgEngine.deliverOfflineMsgs();
|
|
|
|
QVERIFY(numCallbacks == 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
QTEST_GUILESS_MAIN(TestOfflineMsgEngine)
|
|
|
|
#include "offlinemsgengine_test.moc"
|