1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00
qTox/test/model/messageprocessor_test.cpp

166 lines
5.7 KiB
C++
Raw Permalink Normal View History

/*
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/model/message.h"
#include <tox/tox.h>
#include <QObject>
#include <QStringBuilder>
#include <QtTest/QtTest>
namespace {
bool messageHasSelfMention(const Message& message)
{
return std::any_of(message.metadata.begin(), message.metadata.end(), [](MessageMetadata meta) {
return meta.type == MessageMetadataType::selfMention;
});
}
} // namespace
class TestMessageProcessor : public QObject
{
Q_OBJECT
public:
chore: Various code cleanups. * Reorder class data members and/or constructor initialisers to match, reducing confusion about when members will be initialised. * Remove (most) unused variables. Not removed: some global variables with `TODO(sudden6)` on them for using them in the future. I don't know how far into the future sudden6 wants to use them, so I left them there for now. * Distinguish different bootstrap nodes in the logs by index in the bootstrap node list. Originally, we used to log the address/port of the node we're bootstrapping to. This was removed out of privacy concerns (even though the bootstrap nodes are public). This made the logs much less useful when debugging why the client isn't connecting. Having indices makes it easier to see that different nodes are being selected, and makes it possible to determine which node was selected. * Explicitly cast unused results of Tox API functions to `void` when all we want is to know whether the function succeeds or not. * Don't try to `#include <unistd.h>` on Windows. It does not exist on MSVC. * Remove extra `;` after function definitions. * Remove reference indirection of QJsonValueRef, since a copy of that ref (small pointer-like object) has to be made anyway when iterating over QJsonArrays. * Make some file-scope global state `static`. * Use `nullptr` instead of `NULL`. * Add `#if DESKTOP_NOTIFICATIONS` around the code that implements desktop notifications, so it becomes a bit easier to compile everything with a single compiler command - useful for manually running static analysers. * Fix an error on MSVC where `disconnect` is looked up to be a non-static member function and the `this` capture is missing. * Consistently use `struct` and `class` tags for types. * Use references in ranged-for where it reduces copies. * Move private static data members out of the Style class and into file-local scope. There is no need for them to be in the class. Also marked them `const` where possible. * Removed unused lambda capture. * Ensure qTox can compile under NDEBUG with `-Wunused-variable` by inlining the unused variable into the `assert` that was its only target. * Minor reformatting in core_test.cpp.
2020-04-16 23:59:29 +08:00
TestMessageProcessor(){}
private slots:
void testSelfMention();
void testOutgoingMessage();
void testIncomingMessage();
};
/**
* @brief Tests detection of username
*/
void TestMessageProcessor::testSelfMention()
{
MessageProcessor::SharedParams sharedParams(tox_max_message_length(), 10 * 1024 * 1024);;
const QLatin1String testUserName{"MyUserName"};
const QLatin1String testToxPk{
"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"};
sharedParams.onUserNameSet(testUserName);
sharedParams.setPublicKey(testToxPk);
auto messageProcessor = MessageProcessor(sharedParams);
messageProcessor.enableMentions();
for (const auto& str : {testUserName, testToxPk}) {
// Using my name or public key should match
auto processedMessage = messageProcessor.processIncomingCoreMessage(false, str % " hi");
QVERIFY(messageHasSelfMention(processedMessage));
// Action messages should match too
processedMessage = messageProcessor.processIncomingCoreMessage(true, str % " hi");
QVERIFY(messageHasSelfMention(processedMessage));
// Too much text shouldn't match
processedMessage = messageProcessor.processIncomingCoreMessage(false, str % "2");
QVERIFY(!messageHasSelfMention(processedMessage));
// Unless it's a colon
processedMessage = messageProcessor.processIncomingCoreMessage(false, str % ": test");
QVERIFY(messageHasSelfMention(processedMessage));
// remove last character
QString chopped = str;
chopped.chop(1);
// Too little text shouldn't match
processedMessage = messageProcessor.processIncomingCoreMessage(false, chopped);
QVERIFY(!messageHasSelfMention(processedMessage));
// make lower case
QString lower = QString(str).toLower();
// The regex should be case insensitive
processedMessage = messageProcessor.processIncomingCoreMessage(false, lower % " hi");
QVERIFY(messageHasSelfMention(processedMessage));
}
// New user name changes should be detected
sharedParams.onUserNameSet("NewUserName");
auto processedMessage = messageProcessor.processIncomingCoreMessage(false, "NewUserName: hi");
QVERIFY(messageHasSelfMention(processedMessage));
// Special characters should be removed
sharedParams.onUserNameSet("New\nUserName");
processedMessage = messageProcessor.processIncomingCoreMessage(false, "NewUserName: hi");
QVERIFY(messageHasSelfMention(processedMessage));
// Regression tests for: https://github.com/qTox/qTox/issues/2119
{
// Empty usernames should not match
sharedParams.onUserNameSet("");
processedMessage = messageProcessor.processIncomingCoreMessage(false, "");
QVERIFY(!messageHasSelfMention(processedMessage));
// Empty usernames matched on everything, ensure this is not the case
processedMessage = messageProcessor.processIncomingCoreMessage(false, "a");
QVERIFY(!messageHasSelfMention(processedMessage));
}
}
/**
* @brief Tests behavior of the processor for outgoing messages
*/
void TestMessageProcessor::testOutgoingMessage()
{
auto sharedParams = MessageProcessor::SharedParams(tox_max_message_length(), 10 * 1024 * 1024);
auto messageProcessor = MessageProcessor(sharedParams);
QString testStr;
for (size_t i = 0; i < tox_max_message_length() + 50; ++i) {
testStr += "a";
}
auto messages = messageProcessor.processOutgoingMessage(false, testStr, ExtensionSet());
// The message processor should split our messages
QVERIFY(messages.size() == 2);
auto extensionSet = ExtensionSet();
extensionSet[ExtensionType::messages] = true;
messages = messageProcessor.processOutgoingMessage(false, testStr, extensionSet);
// If we have multipart messages we shouldn't split our messages
QVERIFY(messages.size() == 1);
}
/**
* @brief Tests behavior of the processor for incoming messages
*/
void TestMessageProcessor::testIncomingMessage()
{
// Nothing too special happening on the incoming side if we aren't looking for self mentions
auto sharedParams = MessageProcessor::SharedParams(tox_max_message_length(), 10 * 1024 * 1024);
auto messageProcessor = MessageProcessor(sharedParams);
auto message = messageProcessor.processIncomingCoreMessage(false, "test");
QVERIFY(message.isAction == false);
QVERIFY(message.content == "test");
QVERIFY(message.timestamp.isValid());
}
QTEST_GUILESS_MAIN(TestMessageProcessor)
#include "messageprocessor_test.moc"