1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00
qTox/test/model/groupmessagedispatcher_test.cpp
Anthony Bilinski 70824729ff
chore(cleanup): don't use 0 as nullptr
Don't add Wzero-as-null-pointer-constant by default, since on older Qt
versions that we stil support and that our CI runs agains, Qt API themselves
cause warnings which lead to build errors all over the place.

Fix #6008
2020-03-21 23:20:03 -07:00

321 lines
9.3 KiB
C++

/*
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/icoregroupmessagesender.h"
#include "src/model/group.h"
#include "src/model/groupmessagedispatcher.h"
#include "src/model/message.h"
#include "src/persistence/settings.h"
#include <QObject>
#include <QtTest/QtTest>
#include <set>
#include <deque>
class MockGroupMessageSender : public ICoreGroupMessageSender
{
public:
void sendGroupAction(int groupId, const QString& action) override
{
numSentActions++;
}
void sendGroupMessage(int groupId, const QString& message) override
{
numSentMessages++;
}
size_t numSentActions = 0;
size_t numSentMessages = 0;
};
/**
* Mock 1 peer at group number 0
*/
class MockGroupQuery : public ICoreGroupQuery
{
public:
GroupId getGroupPersistentId(uint32_t groupNumber) const override
{
return GroupId();
}
uint32_t getGroupNumberPeers(int groupId) const override
{
if (emptyGroup) {
return 1;
}
return 2;
}
QString getGroupPeerName(int groupId, int peerId) const override
{
return QString("peer") + peerId;
}
ToxPk getGroupPeerPk(int groupId, int peerId) const override
{
uint8_t id[TOX_PUBLIC_KEY_SIZE] = {static_cast<uint8_t>(peerId)};
return ToxPk(id);
}
QStringList getGroupPeerNames(int groupId) const override
{
if (emptyGroup) {
return QStringList({QString("me")});
}
return QStringList({QString("me"), QString("other")});
}
bool getGroupAvEnabled(int groupId) const override
{
return false;
}
void setAsEmptyGroup()
{
emptyGroup = true;
}
void setAsFunctionalGroup()
{
emptyGroup = false;
}
private:
bool emptyGroup = false;
};
class MockCoreIdHandler : public ICoreIdHandler
{
public:
ToxId getSelfId() const override
{
std::terminate();
return ToxId();
}
ToxPk getSelfPublicKey() const override
{
static uint8_t id[TOX_PUBLIC_KEY_SIZE] = {0};
return ToxPk(id);
}
QString getUsername() const override
{
return "me";
}
};
class MockGroupSettings : public IGroupSettings
{
public:
QStringList getBlackList() const override
{
return blacklist;
}
void setBlackList(const QStringList& blist) override
{
blacklist = blist;
}
bool getGroupAlwaysNotify() const override
{
return false;
}
void setGroupAlwaysNotify(bool newValue) override {}
private:
QStringList blacklist;
};
class TestGroupMessageDispatcher : public QObject
{
Q_OBJECT
public:
TestGroupMessageDispatcher();
private slots:
void init();
void testSignals();
void testMessageSending();
void testEmptyGroup();
void testSelfReceive();
void testBlacklist();
void onMessageSent(DispatchedMessageId id, Message message)
{
auto it = outgoingMessages.find(id);
QVERIFY(it == outgoingMessages.end());
outgoingMessages.emplace(id);
sentMessages.push_back(std::move(message));
}
void onMessageComplete(DispatchedMessageId id)
{
auto it = outgoingMessages.find(id);
QVERIFY(it != outgoingMessages.end());
outgoingMessages.erase(it);
}
void onMessageReceived(const ToxPk& sender, Message message)
{
receivedMessages.push_back(std::move(message));
}
private:
// All unique_ptrs to make construction/init() easier to manage
std::unique_ptr<MockGroupSettings> groupSettings;
std::unique_ptr<MockGroupQuery> groupQuery;
std::unique_ptr<MockCoreIdHandler> coreIdHandler;
std::unique_ptr<Group> g;
std::unique_ptr<MockGroupMessageSender> messageSender;
std::unique_ptr<MessageProcessor::SharedParams> sharedProcessorParams;
std::unique_ptr<MessageProcessor> messageProcessor;
std::unique_ptr<GroupMessageDispatcher> groupMessageDispatcher;
std::set<DispatchedMessageId> outgoingMessages;
std::deque<Message> sentMessages;
std::deque<Message> receivedMessages;
};
TestGroupMessageDispatcher::TestGroupMessageDispatcher() {}
/**
* @brief Test initialization. Resets all members to initial state
*/
void TestGroupMessageDispatcher::init()
{
groupSettings = std::unique_ptr<MockGroupSettings>(new MockGroupSettings());
groupQuery = std::unique_ptr<MockGroupQuery>(new MockGroupQuery());
coreIdHandler = std::unique_ptr<MockCoreIdHandler>(new MockCoreIdHandler());
g = std::unique_ptr<Group>(
new Group(0, GroupId(), "TestGroup", false, "me", *groupQuery, *coreIdHandler));
messageSender = std::unique_ptr<MockGroupMessageSender>(new MockGroupMessageSender());
sharedProcessorParams =
std::unique_ptr<MessageProcessor::SharedParams>(new MessageProcessor::SharedParams());
messageProcessor = std::unique_ptr<MessageProcessor>(new MessageProcessor(*sharedProcessorParams));
groupMessageDispatcher = std::unique_ptr<GroupMessageDispatcher>(
new GroupMessageDispatcher(*g, *messageProcessor, *coreIdHandler, *messageSender,
*groupSettings));
connect(groupMessageDispatcher.get(), &GroupMessageDispatcher::messageSent, this,
&TestGroupMessageDispatcher::onMessageSent);
connect(groupMessageDispatcher.get(), &GroupMessageDispatcher::messageComplete, this,
&TestGroupMessageDispatcher::onMessageComplete);
connect(groupMessageDispatcher.get(), &GroupMessageDispatcher::messageReceived, this,
&TestGroupMessageDispatcher::onMessageReceived);
outgoingMessages = std::set<DispatchedMessageId>();
sentMessages = std::deque<Message>();
receivedMessages = std::deque<Message>();
}
/**
* @brief Tests that the signals emitted by the dispatcher are all emitted at the correct times
*/
void TestGroupMessageDispatcher::testSignals()
{
groupMessageDispatcher->sendMessage(false, "test");
// For groups we pair our sent and completed signals since we have no receiver reports
QVERIFY(outgoingMessages.size() == 0);
QVERIFY(!sentMessages.empty());
QVERIFY(sentMessages.front().isAction == false);
QVERIFY(sentMessages.front().content == "test");
// If signals are emitted correctly we should have one message in our received message buffer
QVERIFY(receivedMessages.empty());
groupMessageDispatcher->onMessageReceived(ToxPk(), false, "test2");
QVERIFY(!receivedMessages.empty());
QVERIFY(receivedMessages.front().isAction == false);
QVERIFY(receivedMessages.front().content == "test2");
}
/**
* @brief Tests that sent messages actually go through to core
*/
void TestGroupMessageDispatcher::testMessageSending()
{
groupMessageDispatcher->sendMessage(false, "Test");
QVERIFY(messageSender->numSentMessages == 1);
QVERIFY(messageSender->numSentActions == 0);
groupMessageDispatcher->sendMessage(true, "Test");
QVERIFY(messageSender->numSentMessages == 1);
QVERIFY(messageSender->numSentActions == 1);
}
/**
* @brief Tests that if we are the only member in a group we do _not_ send messages to core. Toxcore
* isn't too happy if we send messages and we're the only one in the group
*/
void TestGroupMessageDispatcher::testEmptyGroup()
{
groupQuery->setAsEmptyGroup();
g->regeneratePeerList();
groupMessageDispatcher->sendMessage(false, "Test");
groupMessageDispatcher->sendMessage(true, "Test");
QVERIFY(messageSender->numSentMessages == 0);
QVERIFY(messageSender->numSentActions == 0);
}
/**
* @brief Tests that we do not emit any signals if we receive a message from ourself. Toxcore will send us back messages we sent
*/
void TestGroupMessageDispatcher::testSelfReceive()
{
uint8_t selfId[TOX_PUBLIC_KEY_SIZE] = {0};
groupMessageDispatcher->onMessageReceived(ToxPk(selfId), false, "Test");
QVERIFY(receivedMessages.size() == 0);
uint8_t id[TOX_PUBLIC_KEY_SIZE] = {1};
groupMessageDispatcher->onMessageReceived(ToxPk(id), false, "Test");
QVERIFY(receivedMessages.size() == 1);
}
/**
* @brief Tests that messages from blacklisted peers do not get propogated from the dispatcher
*/
void TestGroupMessageDispatcher::testBlacklist()
{
uint8_t id[TOX_PUBLIC_KEY_SIZE] = {1};
auto otherPk = ToxPk(id);
groupMessageDispatcher->onMessageReceived(otherPk, false, "Test");
QVERIFY(receivedMessages.size() == 1);
groupSettings->setBlackList({otherPk.toString()});
groupMessageDispatcher->onMessageReceived(otherPk, false, "Test");
QVERIFY(receivedMessages.size() == 1);
}
// Cannot be guiless due to a settings instance in GroupMessageDispatcher
QTEST_GUILESS_MAIN(TestGroupMessageDispatcher)
#include "groupmessagedispatcher_test.moc"