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 1206da2b05
refactor(ToxPk): Don't define model's ToxPk, ToxId, GroupId from tox.h
Since they exist in saved settings and the chat database, they are their own
size. assert that it matches tox.h's size in Core constructor, though.
2022-03-13 05:28:41 -07:00

259 lines
8.5 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 "src/persistence/igroupsettings.h"
#include "util/interface.h"
#include "mock/mockcoreidhandler.h"
#include "mock/mockgroupquery.h"
#include <QObject>
#include <QtTest/QtTest>
#include <set>
#include <deque>
class MockGroupMessageSender : public ICoreGroupMessageSender
{
public:
void sendGroupAction(int groupId, const QString& action) override;
void sendGroupMessage(int groupId, const QString& message) override;
size_t numSentActions = 0;
size_t numSentMessages = 0;
};
void MockGroupMessageSender::sendGroupAction(int groupId, const QString& action)
{
std::ignore = groupId;
std::ignore = action;
numSentActions++;
}
void MockGroupMessageSender::sendGroupMessage(int groupId, const QString& message)
{
std::ignore = groupId;
std::ignore = message;
numSentMessages++;
}
class MockGroupSettings : public QObject, public IGroupSettings
{
Q_OBJECT
public:
QStringList getBlackList() const override;
void setBlackList(const QStringList& blist) override;
SIGNAL_IMPL(MockGroupSettings, blackListChanged, QStringList const& blist)
bool getShowGroupJoinLeaveMessages() const override { return true; };
void setShowGroupJoinLeaveMessages(bool newValue) override { std::ignore = newValue; };
SIGNAL_IMPL(MockGroupSettings, showGroupJoinLeaveMessagesChanged, bool show)
private:
QStringList blacklist;
};
QStringList MockGroupSettings::getBlackList() const
{
return blacklist;
}
void MockGroupSettings::setBlackList(const QStringList& blist)
{
blacklist = blist;
}
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)
{
std::ignore = sender;
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(tox_max_message_length(), 10 * 1024 * 1024));
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[ToxPk::size] = {0};
groupMessageDispatcher->onMessageReceived(ToxPk(selfId), false, "Test");
QVERIFY(receivedMessages.size() == 0);
uint8_t id[ToxPk::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[ToxPk::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"