mirror of https://github.com/qTox/qTox.git
9 changed files with 392 additions and 77 deletions
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
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/>.
|
||||
*/ |
||||
|
||||
#ifndef ICORE_FRIEND_MESSAGE_SENDER_H |
||||
#define ICORE_FRIEND_MESSAGE_SENDER_H |
||||
|
||||
#include "receiptnum.h" |
||||
|
||||
#include <QString> |
||||
#include <cstdint> |
||||
|
||||
class ICoreFriendMessageSender |
||||
{ |
||||
public: |
||||
virtual bool sendAction(uint32_t friendId, const QString& action, ReceiptNum& receipt) = 0; |
||||
virtual bool sendMessage(uint32_t friendId, const QString& message, ReceiptNum& receipt) = 0; |
||||
}; |
||||
|
||||
|
||||
#endif /* ICORE_FRIEND_MESSAGE_SENDER_H */ |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
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/>.
|
||||
*/ |
||||
|
||||
#ifndef RECEIPT_NUM_H |
||||
#define RECEIPT_NUM_H |
||||
|
||||
#include "src/util/strongtype.h" |
||||
|
||||
#include <QMetaType> |
||||
#include <cstdint> |
||||
|
||||
using ReceiptNum = NamedType<uint32_t, struct ReceiptNumTag>; |
||||
Q_DECLARE_METATYPE(ReceiptNum); |
||||
|
||||
#endif /* RECEIPT_NUM_H */ |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
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/>.
|
||||
*/ |
||||
|
||||
#ifndef MESSAGE_H |
||||
#define MESSAGE_H |
||||
|
||||
#include <QDateTime> |
||||
#include <QString> |
||||
|
||||
struct Message |
||||
{ |
||||
bool isAction; |
||||
QString content; |
||||
QDateTime timestamp; |
||||
}; |
||||
|
||||
#endif /*MESSAGE_H*/ |
@ -0,0 +1,193 @@
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
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" |
||||
#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 |
||||
{ |
||||
if (f->isOnline()) { |
||||
receipt.get() = receiptNum++; |
||||
if (!dropReceipts) { |
||||
msgs.push_back(message); |
||||
emit receiptReceived(receipt); |
||||
} |
||||
numMessagesSent++; |
||||
} else { |
||||
numMessagesFailed++; |
||||
} |
||||
return f->isOnline(); |
||||
} |
||||
|
||||
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" |
Loading…
Reference in new issue