mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Fix memory leaks & data races in tests (#4772)
* Add a few pre-made sanitizer suppressions * Test Sanitization: Fix threading issues * Test Sanitization: Allow deletion of PubSub We still don't delete it in main code, but this allows us to try deleting it in tests. * Test Sanitization: Fix some memory leaks * fix gtest clang-tidy warning * const emojis test :-)
This commit is contained in:
parent
ac6708b3a2
commit
3f7671000a
18 changed files with 360 additions and 296 deletions
|
@ -36,8 +36,12 @@ CheckOptions:
|
||||||
value: CamelCase
|
value: CamelCase
|
||||||
- key: readability-identifier-naming.EnumCase
|
- key: readability-identifier-naming.EnumCase
|
||||||
value: CamelCase
|
value: CamelCase
|
||||||
|
|
||||||
- key: readability-identifier-naming.FunctionCase
|
- key: readability-identifier-naming.FunctionCase
|
||||||
value: camelBack
|
value: camelBack
|
||||||
|
- key: readability-identifier-naming.FunctionIgnoredRegexp
|
||||||
|
value: ^TEST$
|
||||||
|
|
||||||
- key: readability-identifier-naming.MemberCase
|
- key: readability-identifier-naming.MemberCase
|
||||||
value: camelBack
|
value: camelBack
|
||||||
- key: readability-identifier-naming.PrivateMemberIgnoredRegexp
|
- key: readability-identifier-naming.PrivateMemberIgnoredRegexp
|
||||||
|
|
2
.sanitizers/asan-suppressions
Normal file
2
.sanitizers/asan-suppressions
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Ignore openssl issues
|
||||||
|
interceptor_via_lib:libcrypto.so.3
|
3
.sanitizers/lsan-suppressions
Normal file
3
.sanitizers/lsan-suppressions
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Ignore openssl issues
|
||||||
|
leak:libcrypto.so.3
|
||||||
|
leak:CRYPTO_zalloc
|
17
.sanitizers/tsan-suppressions
Normal file
17
.sanitizers/tsan-suppressions
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
race:libdbus-1.so.3
|
||||||
|
deadlock:libdbus-1.so.3
|
||||||
|
race:libglib-2.0.so.0
|
||||||
|
race:libgio-2.0.so.0
|
||||||
|
|
||||||
|
# Not sure about these suppression
|
||||||
|
# race:qscopedpointer.h
|
||||||
|
# race:qarraydata.cpp
|
||||||
|
# race:qarraydata.h
|
||||||
|
# race:qarraydataops.h
|
||||||
|
# race:libQt6Core.so.6
|
||||||
|
# race:libQt6Gui.so.6
|
||||||
|
# race:libQt6XcbQpa.so.6
|
||||||
|
# race:libQt6Network.so.6
|
||||||
|
|
||||||
|
# very not sure about this one
|
||||||
|
# race:qstring.h
|
2
.sanitizers/ubsan-suppressions
Normal file
2
.sanitizers/ubsan-suppressions
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
enum:NetworkResult.hpp
|
||||||
|
enum:gtest.h
|
|
@ -7,6 +7,8 @@ namespace chatterino::mock {
|
||||||
class EmptyApplication : public IApplication
|
class EmptyApplication : public IApplication
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual ~EmptyApplication() = default;
|
||||||
|
|
||||||
Theme *getThemes() override
|
Theme *getThemes() override
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -33,6 +33,7 @@ inline QDebug operator<<(QDebug dbg, const ActionUser &user)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PubSubAction {
|
struct PubSubAction {
|
||||||
|
PubSubAction() = default;
|
||||||
PubSubAction(const QJsonObject &data, const QString &_roomID);
|
PubSubAction(const QJsonObject &data, const QString &_roomID);
|
||||||
ActionUser source;
|
ActionUser source;
|
||||||
|
|
||||||
|
|
|
@ -77,8 +77,6 @@ public:
|
||||||
|
|
||||||
void setAccountData(QString token, QString userID);
|
void setAccountData(QString token, QString userID);
|
||||||
|
|
||||||
~PubSub() = delete;
|
|
||||||
|
|
||||||
enum class State {
|
enum class State {
|
||||||
Connected,
|
Connected,
|
||||||
Disconnected,
|
Disconnected,
|
||||||
|
|
|
@ -31,7 +31,8 @@ struct PubSubAutoModQueueMessage {
|
||||||
QString senderUserDisplayName;
|
QString senderUserDisplayName;
|
||||||
QColor senderUserChatColor;
|
QColor senderUserChatColor;
|
||||||
|
|
||||||
PubSubAutoModQueueMessage(const QJsonObject &root);
|
PubSubAutoModQueueMessage() = default;
|
||||||
|
explicit PubSubAutoModQueueMessage(const QJsonObject &root);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -28,7 +28,8 @@ struct PubSubWhisperMessage {
|
||||||
QString fromUserDisplayName;
|
QString fromUserDisplayName;
|
||||||
QColor fromUserColor;
|
QColor fromUserColor;
|
||||||
|
|
||||||
PubSubWhisperMessage(const QJsonObject &root);
|
PubSubWhisperMessage() = default;
|
||||||
|
explicit PubSubWhisperMessage(const QJsonObject &root);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -5,6 +5,7 @@ option(CHATTERINO_TEST_USE_PUBLIC_HTTPBIN "Use public httpbin for testing networ
|
||||||
set(test_SOURCES
|
set(test_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/main.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/main.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/resources/test-resources.qrc
|
${CMAKE_CURRENT_LIST_DIR}/resources/test-resources.qrc
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/TestHelpers.hpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/ChannelChatters.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/ChannelChatters.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/AccessGuard.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/AccessGuard.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/NetworkCommon.cpp
|
${CMAKE_CURRENT_LIST_DIR}/src/NetworkCommon.cpp
|
||||||
|
|
|
@ -116,33 +116,33 @@ private:
|
||||||
TEST(BasicPubSub, SubscriptionCycle)
|
TEST(BasicPubSub, SubscriptionCycle)
|
||||||
{
|
{
|
||||||
const QString host("wss://127.0.0.1:9050/liveupdates/sub-unsub");
|
const QString host("wss://127.0.0.1:9050/liveupdates/sub-unsub");
|
||||||
auto *manager = new MyManager(host);
|
MyManager manager(host);
|
||||||
manager->start();
|
manager.start();
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
manager->sub({1, "foo"});
|
manager.sub({1, "foo"});
|
||||||
std::this_thread::sleep_for(500ms);
|
std::this_thread::sleep_for(500ms);
|
||||||
|
|
||||||
ASSERT_EQ(manager->diag.connectionsOpened, 1);
|
ASSERT_EQ(manager.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(manager->diag.connectionsClosed, 0);
|
ASSERT_EQ(manager.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(manager->diag.connectionsFailed, 0);
|
ASSERT_EQ(manager.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(manager->messagesReceived, 1);
|
ASSERT_EQ(manager.messagesReceived, 1);
|
||||||
|
|
||||||
ASSERT_EQ(manager->popMessage(), QString("ack-sub-1-foo"));
|
ASSERT_EQ(manager.popMessage(), QString("ack-sub-1-foo"));
|
||||||
|
|
||||||
manager->unsub({1, "foo"});
|
manager.unsub({1, "foo"});
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
|
|
||||||
ASSERT_EQ(manager->diag.connectionsOpened, 1);
|
ASSERT_EQ(manager.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(manager->diag.connectionsClosed, 0);
|
ASSERT_EQ(manager.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(manager->diag.connectionsFailed, 0);
|
ASSERT_EQ(manager.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(manager->messagesReceived, 2);
|
ASSERT_EQ(manager.messagesReceived, 2);
|
||||||
ASSERT_EQ(manager->popMessage(), QString("ack-unsub-1-foo"));
|
ASSERT_EQ(manager.popMessage(), QString("ack-unsub-1-foo"));
|
||||||
|
|
||||||
manager->stop();
|
manager.stop();
|
||||||
|
|
||||||
ASSERT_EQ(manager->diag.connectionsOpened, 1);
|
ASSERT_EQ(manager.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(manager->diag.connectionsClosed, 1);
|
ASSERT_EQ(manager.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(manager->diag.connectionsFailed, 0);
|
ASSERT_EQ(manager.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(manager->messagesReceived, 2);
|
ASSERT_EQ(manager.messagesReceived, 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
using namespace chatterino;
|
using namespace chatterino;
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
@ -13,30 +15,30 @@ const QString TARGET_USER_NAME = "Alien";
|
||||||
TEST(BttvLiveUpdates, AllEvents)
|
TEST(BttvLiveUpdates, AllEvents)
|
||||||
{
|
{
|
||||||
const QString host("wss://127.0.0.1:9050/liveupdates/bttv/all-events");
|
const QString host("wss://127.0.0.1:9050/liveupdates/bttv/all-events");
|
||||||
auto *liveUpdates = new BttvLiveUpdates(host);
|
chatterino::BttvLiveUpdates liveUpdates(host);
|
||||||
liveUpdates->start();
|
liveUpdates.start();
|
||||||
|
|
||||||
boost::optional<BttvLiveUpdateEmoteUpdateAddMessage> addMessage;
|
boost::optional<BttvLiveUpdateEmoteUpdateAddMessage> addMessage;
|
||||||
boost::optional<BttvLiveUpdateEmoteUpdateAddMessage> updateMessage;
|
boost::optional<BttvLiveUpdateEmoteUpdateAddMessage> updateMessage;
|
||||||
boost::optional<BttvLiveUpdateEmoteRemoveMessage> removeMessage;
|
boost::optional<BttvLiveUpdateEmoteRemoveMessage> removeMessage;
|
||||||
|
|
||||||
liveUpdates->signals_.emoteAdded.connect([&](const auto &m) {
|
std::ignore = liveUpdates.signals_.emoteAdded.connect([&](const auto &m) {
|
||||||
addMessage = m;
|
addMessage = m;
|
||||||
});
|
});
|
||||||
liveUpdates->signals_.emoteUpdated.connect([&](const auto &m) {
|
std::ignore = liveUpdates.signals_.emoteUpdated.connect([&](const auto &m) {
|
||||||
updateMessage = m;
|
updateMessage = m;
|
||||||
});
|
});
|
||||||
liveUpdates->signals_.emoteRemoved.connect([&](const auto &m) {
|
std::ignore = liveUpdates.signals_.emoteRemoved.connect([&](const auto &m) {
|
||||||
removeMessage = m;
|
removeMessage = m;
|
||||||
});
|
});
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
liveUpdates->joinChannel(TARGET_USER_ID, TARGET_USER_NAME);
|
liveUpdates.joinChannel(TARGET_USER_ID, TARGET_USER_NAME);
|
||||||
std::this_thread::sleep_for(500ms);
|
std::this_thread::sleep_for(500ms);
|
||||||
|
|
||||||
ASSERT_EQ(liveUpdates->diag.connectionsOpened, 1);
|
ASSERT_EQ(liveUpdates.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(liveUpdates->diag.connectionsClosed, 0);
|
ASSERT_EQ(liveUpdates.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(liveUpdates->diag.connectionsFailed, 0);
|
ASSERT_EQ(liveUpdates.diag.connectionsFailed, 0);
|
||||||
|
|
||||||
auto add = *addMessage;
|
auto add = *addMessage;
|
||||||
ASSERT_EQ(add.channelID, TARGET_USER_ID);
|
ASSERT_EQ(add.channelID, TARGET_USER_ID);
|
||||||
|
@ -52,8 +54,8 @@ TEST(BttvLiveUpdates, AllEvents)
|
||||||
ASSERT_EQ(rem.channelID, TARGET_USER_ID);
|
ASSERT_EQ(rem.channelID, TARGET_USER_ID);
|
||||||
ASSERT_EQ(rem.emoteID, QString("55898e122612142e6aaa935b"));
|
ASSERT_EQ(rem.emoteID, QString("55898e122612142e6aaa935b"));
|
||||||
|
|
||||||
liveUpdates->stop();
|
liveUpdates.stop();
|
||||||
ASSERT_EQ(liveUpdates->diag.connectionsOpened, 1);
|
ASSERT_EQ(liveUpdates.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(liveUpdates->diag.connectionsClosed, 1);
|
ASSERT_EQ(liveUpdates.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(liveUpdates->diag.connectionsFailed, 0);
|
ASSERT_EQ(liveUpdates.diag.connectionsFailed, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ TEST(Emojis, ShortcodeParsing)
|
||||||
QString expectedOutput;
|
QString expectedOutput;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<TestCase> tests{
|
const std::vector<TestCase> tests{
|
||||||
{
|
{
|
||||||
// input
|
// input
|
||||||
"foo :penguin: bar",
|
"foo :penguin: bar",
|
||||||
|
|
|
@ -19,34 +19,34 @@ const QString TARGET_USER_ID = "60b39e943e203cc169dfc106";
|
||||||
TEST(SeventvEventAPI, AllEvents)
|
TEST(SeventvEventAPI, AllEvents)
|
||||||
{
|
{
|
||||||
const QString host("wss://127.0.0.1:9050/liveupdates/seventv/all-events");
|
const QString host("wss://127.0.0.1:9050/liveupdates/seventv/all-events");
|
||||||
auto *eventAPI = new SeventvEventAPI(host, std::chrono::milliseconds(1000));
|
SeventvEventAPI eventAPI(host, std::chrono::milliseconds(1000));
|
||||||
eventAPI->start();
|
eventAPI.start();
|
||||||
|
|
||||||
boost::optional<EmoteAddDispatch> addDispatch;
|
boost::optional<EmoteAddDispatch> addDispatch;
|
||||||
boost::optional<EmoteUpdateDispatch> updateDispatch;
|
boost::optional<EmoteUpdateDispatch> updateDispatch;
|
||||||
boost::optional<EmoteRemoveDispatch> removeDispatch;
|
boost::optional<EmoteRemoveDispatch> removeDispatch;
|
||||||
boost::optional<UserConnectionUpdateDispatch> userDispatch;
|
boost::optional<UserConnectionUpdateDispatch> userDispatch;
|
||||||
|
|
||||||
eventAPI->signals_.emoteAdded.connect([&](const auto &d) {
|
eventAPI.signals_.emoteAdded.connect([&](const auto &d) {
|
||||||
addDispatch = d;
|
addDispatch = d;
|
||||||
});
|
});
|
||||||
eventAPI->signals_.emoteUpdated.connect([&](const auto &d) {
|
eventAPI.signals_.emoteUpdated.connect([&](const auto &d) {
|
||||||
updateDispatch = d;
|
updateDispatch = d;
|
||||||
});
|
});
|
||||||
eventAPI->signals_.emoteRemoved.connect([&](const auto &d) {
|
eventAPI.signals_.emoteRemoved.connect([&](const auto &d) {
|
||||||
removeDispatch = d;
|
removeDispatch = d;
|
||||||
});
|
});
|
||||||
eventAPI->signals_.userUpdated.connect([&](const auto &d) {
|
eventAPI.signals_.userUpdated.connect([&](const auto &d) {
|
||||||
userDispatch = d;
|
userDispatch = d;
|
||||||
});
|
});
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
eventAPI->subscribeUser("", EMOTE_SET_A);
|
eventAPI.subscribeUser("", EMOTE_SET_A);
|
||||||
std::this_thread::sleep_for(500ms);
|
std::this_thread::sleep_for(500ms);
|
||||||
|
|
||||||
ASSERT_EQ(eventAPI->diag.connectionsOpened, 1);
|
ASSERT_EQ(eventAPI.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(eventAPI->diag.connectionsClosed, 0);
|
ASSERT_EQ(eventAPI.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(eventAPI->diag.connectionsFailed, 0);
|
ASSERT_EQ(eventAPI.diag.connectionsFailed, 0);
|
||||||
|
|
||||||
auto add = *addDispatch;
|
auto add = *addDispatch;
|
||||||
ASSERT_EQ(add.emoteSetID, EMOTE_SET_A);
|
ASSERT_EQ(add.emoteSetID, EMOTE_SET_A);
|
||||||
|
@ -71,7 +71,7 @@ TEST(SeventvEventAPI, AllEvents)
|
||||||
updateDispatch = boost::none;
|
updateDispatch = boost::none;
|
||||||
removeDispatch = boost::none;
|
removeDispatch = boost::none;
|
||||||
|
|
||||||
eventAPI->subscribeUser(TARGET_USER_ID, "");
|
eventAPI.subscribeUser(TARGET_USER_ID, "");
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
|
|
||||||
ASSERT_EQ(addDispatch.has_value(), false);
|
ASSERT_EQ(addDispatch.has_value(), false);
|
||||||
|
@ -85,24 +85,24 @@ TEST(SeventvEventAPI, AllEvents)
|
||||||
ASSERT_EQ(user.emoteSetID, EMOTE_SET_B);
|
ASSERT_EQ(user.emoteSetID, EMOTE_SET_B);
|
||||||
ASSERT_EQ(user.connectionIndex, 0);
|
ASSERT_EQ(user.connectionIndex, 0);
|
||||||
|
|
||||||
eventAPI->stop();
|
eventAPI.stop();
|
||||||
ASSERT_EQ(eventAPI->diag.connectionsOpened, 1);
|
ASSERT_EQ(eventAPI.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(eventAPI->diag.connectionsClosed, 1);
|
ASSERT_EQ(eventAPI.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(eventAPI->diag.connectionsFailed, 0);
|
ASSERT_EQ(eventAPI.diag.connectionsFailed, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SeventvEventAPI, NoHeartbeat)
|
TEST(SeventvEventAPI, NoHeartbeat)
|
||||||
{
|
{
|
||||||
const QString host("wss://127.0.0.1:9050/liveupdates/seventv/no-heartbeat");
|
const QString host("wss://127.0.0.1:9050/liveupdates/seventv/no-heartbeat");
|
||||||
auto *eventApi = new SeventvEventAPI(host, std::chrono::milliseconds(1000));
|
SeventvEventAPI eventApi(host, std::chrono::milliseconds(1000));
|
||||||
eventApi->start();
|
eventApi.start();
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
eventApi->subscribeUser("", EMOTE_SET_A);
|
eventApi.subscribeUser("", EMOTE_SET_A);
|
||||||
std::this_thread::sleep_for(1250ms);
|
std::this_thread::sleep_for(1250ms);
|
||||||
ASSERT_EQ(eventApi->diag.connectionsOpened, 2);
|
ASSERT_EQ(eventApi.diag.connectionsOpened, 2);
|
||||||
ASSERT_EQ(eventApi->diag.connectionsClosed, 1);
|
ASSERT_EQ(eventApi.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(eventApi->diag.connectionsFailed, 0);
|
ASSERT_EQ(eventApi.diag.connectionsFailed, 0);
|
||||||
|
|
||||||
eventApi->stop();
|
eventApi.stop();
|
||||||
}
|
}
|
||||||
|
|
44
tests/src/TestHelpers.hpp
Normal file
44
tests/src/TestHelpers.hpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class ReceivedMessage
|
||||||
|
{
|
||||||
|
mutable std::mutex mutex;
|
||||||
|
|
||||||
|
bool isSet{false};
|
||||||
|
T t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ReceivedMessage() = default;
|
||||||
|
|
||||||
|
explicit operator bool() const
|
||||||
|
{
|
||||||
|
std::unique_lock lock(this->mutex);
|
||||||
|
|
||||||
|
return this->isSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceivedMessage &operator=(const T &newT)
|
||||||
|
{
|
||||||
|
std::unique_lock lock(this->mutex);
|
||||||
|
|
||||||
|
this->isSet = true;
|
||||||
|
this->t = newT;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const T &otherT) const
|
||||||
|
{
|
||||||
|
std::unique_lock lock(this->mutex);
|
||||||
|
|
||||||
|
return this->t == otherT;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T *operator->() const
|
||||||
|
{
|
||||||
|
return &this->t;
|
||||||
|
}
|
||||||
|
};
|
|
@ -154,7 +154,7 @@ TEST(TwitchMessageBuilder, BadgeInfoParsing)
|
||||||
|
|
||||||
for (const auto &test : testCases)
|
for (const auto &test : testCases)
|
||||||
{
|
{
|
||||||
auto privmsg =
|
auto *privmsg =
|
||||||
Communi::IrcPrivateMessage::fromData(test.input, nullptr);
|
Communi::IrcPrivateMessage::fromData(test.input, nullptr);
|
||||||
|
|
||||||
auto outputBadgeInfo =
|
auto outputBadgeInfo =
|
||||||
|
@ -166,6 +166,8 @@ TEST(TwitchMessageBuilder, BadgeInfoParsing)
|
||||||
SharedMessageBuilder::parseBadgeTag(privmsg->tags());
|
SharedMessageBuilder::parseBadgeTag(privmsg->tags());
|
||||||
EXPECT_EQ(outputBadges, test.expectedBadges)
|
EXPECT_EQ(outputBadges, test.expectedBadges)
|
||||||
<< "Input for badges " << test.input.toStdString() << " failed";
|
<< "Input for badges " << test.input.toStdString() << " failed";
|
||||||
|
|
||||||
|
delete privmsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,5 +345,7 @@ TEST_F(TestTwitchMessageBuilder, ParseTwitchEmotes)
|
||||||
EXPECT_EQ(actualTwitchEmotes, test.expectedTwitchEmotes)
|
EXPECT_EQ(actualTwitchEmotes, test.expectedTwitchEmotes)
|
||||||
<< "Input for twitch emotes " << test.input.toStdString()
|
<< "Input for twitch emotes " << test.input.toStdString()
|
||||||
<< " failed";
|
<< " failed";
|
||||||
|
|
||||||
|
delete privmsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,13 @@
|
||||||
#include "providers/twitch/PubSubManager.hpp"
|
#include "providers/twitch/PubSubManager.hpp"
|
||||||
#include "providers/twitch/pubsubmessages/AutoMod.hpp"
|
#include "providers/twitch/pubsubmessages/AutoMod.hpp"
|
||||||
#include "providers/twitch/pubsubmessages/Whisper.hpp"
|
#include "providers/twitch/pubsubmessages/Whisper.hpp"
|
||||||
|
#include "TestHelpers.hpp"
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
using namespace chatterino;
|
using namespace chatterino;
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
@ -30,415 +32,395 @@ using namespace std::chrono_literals;
|
||||||
|
|
||||||
#ifdef RUN_PUBSUB_TESTS
|
#ifdef RUN_PUBSUB_TESTS
|
||||||
|
|
||||||
|
class FTest : public PubSub
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit FTest(const char *path, std::chrono::seconds pingInterval)
|
||||||
|
: PubSub(QString("wss://127.0.0.1:9050%1").arg(path), pingInterval)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
TEST(TwitchPubSubClient, ServerRespondsToPings)
|
TEST(TwitchPubSubClient, ServerRespondsToPings)
|
||||||
{
|
{
|
||||||
auto pingInterval = std::chrono::seconds(1);
|
FTest pubSub("", 1s);
|
||||||
const QString host("wss://127.0.0.1:9050");
|
|
||||||
|
|
||||||
auto *pubSub = new PubSub(host, pingInterval);
|
pubSub.setAccountData("token", "123456");
|
||||||
pubSub->setAccountData("token", "123456");
|
pubSub.start();
|
||||||
pubSub->start();
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 0);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 0);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 0);
|
||||||
|
|
||||||
pubSub->listenToTopic("test");
|
pubSub.listenToTopic("test");
|
||||||
|
|
||||||
std::this_thread::sleep_for(150ms);
|
std::this_thread::sleep_for(150ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 2);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 2);
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 1);
|
ASSERT_EQ(pubSub.diag.listenResponses, 1);
|
||||||
|
|
||||||
std::this_thread::sleep_for(2s);
|
std::this_thread::sleep_for(2s);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 4);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 4);
|
||||||
|
|
||||||
pubSub->stop();
|
pubSub.stop();
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 1);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 4);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 4);
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 1);
|
ASSERT_EQ(pubSub.diag.listenResponses, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TwitchPubSubClient, ServerDoesntRespondToPings)
|
TEST(TwitchPubSubClient, ServerDoesntRespondToPings)
|
||||||
{
|
{
|
||||||
auto pingInterval = std::chrono::seconds(1);
|
FTest pubSub("/dont-respond-to-ping", 1s);
|
||||||
const QString host("wss://127.0.0.1:9050/dont-respond-to-ping");
|
|
||||||
|
|
||||||
auto *pubSub = new PubSub(host, pingInterval);
|
pubSub.setAccountData("token", "123456");
|
||||||
pubSub->setAccountData("token", "123456");
|
pubSub.start();
|
||||||
pubSub->start();
|
pubSub.listenToTopic("test");
|
||||||
pubSub->listenToTopic("test");
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(750ms);
|
std::this_thread::sleep_for(750ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 1);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 1);
|
||||||
|
|
||||||
std::this_thread::sleep_for(500ms);
|
std::this_thread::sleep_for(500ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 2);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 2);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 1);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 2);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 2);
|
||||||
|
|
||||||
pubSub->stop();
|
pubSub.stop();
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 2);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 2);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 2);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 2);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 2);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TwitchPubSubClient, DisconnectedAfter1s)
|
TEST(TwitchPubSubClient, DisconnectedAfter1s)
|
||||||
{
|
{
|
||||||
auto pingInterval = std::chrono::seconds(10);
|
FTest pubSub("/disconnect-client-after-1s", 10s);
|
||||||
const QString host("wss://127.0.0.1:9050/disconnect-client-after-1s");
|
|
||||||
|
|
||||||
auto *pubSub = new PubSub(host, pingInterval);
|
pubSub.setAccountData("token", "123456");
|
||||||
pubSub->setAccountData("token", "123456");
|
pubSub.start();
|
||||||
pubSub->start();
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 0);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 0);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 0);
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 0);
|
ASSERT_EQ(pubSub.diag.listenResponses, 0);
|
||||||
|
|
||||||
pubSub->listenToTopic("test");
|
pubSub.listenToTopic("test");
|
||||||
|
|
||||||
std::this_thread::sleep_for(500ms);
|
std::this_thread::sleep_for(500ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 2); // Listen RESPONSE & Pong
|
ASSERT_EQ(pubSub.diag.messagesReceived, 2); // Listen RESPONSE & Pong
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 1);
|
ASSERT_EQ(pubSub.diag.listenResponses, 1);
|
||||||
|
|
||||||
std::this_thread::sleep_for(350ms);
|
std::this_thread::sleep_for(350ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 2);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 2);
|
||||||
|
|
||||||
std::this_thread::sleep_for(600ms);
|
std::this_thread::sleep_for(600ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 2);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 2);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 1);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 2);
|
ASSERT_EQ(pubSub.diag.listenResponses, 2);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 4); // new listen & new pong
|
ASSERT_EQ(pubSub.diag.messagesReceived, 4); // new listen & new pong
|
||||||
|
|
||||||
pubSub->stop();
|
pubSub.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TwitchPubSubClient, ExceedTopicLimit)
|
TEST(TwitchPubSubClient, ExceedTopicLimit)
|
||||||
{
|
{
|
||||||
auto pingInterval = std::chrono::seconds(1);
|
FTest pubSub("", 1s);
|
||||||
const QString host("wss://127.0.0.1:9050");
|
|
||||||
|
|
||||||
auto *pubSub = new PubSub(host, pingInterval);
|
pubSub.setAccountData("token", "123456");
|
||||||
pubSub->setAccountData("token", "123456");
|
pubSub.start();
|
||||||
pubSub->start();
|
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 0);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 0);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 0);
|
||||||
|
|
||||||
for (auto i = 0; i < PubSubClient::MAX_LISTENS; ++i)
|
for (auto i = 0; i < PubSubClient::MAX_LISTENS; ++i)
|
||||||
{
|
{
|
||||||
pubSub->listenToTopic(QString("test-1.%1").arg(i));
|
pubSub.listenToTopic(QString("test-1.%1").arg(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
|
|
||||||
for (auto i = 0; i < PubSubClient::MAX_LISTENS; ++i)
|
for (auto i = 0; i < PubSubClient::MAX_LISTENS; ++i)
|
||||||
{
|
{
|
||||||
pubSub->listenToTopic(QString("test-2.%1").arg(i));
|
pubSub.listenToTopic(QString("test-2.%1").arg(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 2);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 2);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
|
|
||||||
pubSub->stop();
|
pubSub.stop();
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 2);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 2);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 2);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 2);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TwitchPubSubClient, ExceedTopicLimitSingleStep)
|
TEST(TwitchPubSubClient, ExceedTopicLimitSingleStep)
|
||||||
{
|
{
|
||||||
auto pingInterval = std::chrono::seconds(1);
|
FTest pubSub("", 1s);
|
||||||
const QString host("wss://127.0.0.1:9050");
|
|
||||||
|
|
||||||
auto *pubSub = new PubSub(host, pingInterval);
|
pubSub.setAccountData("token", "123456");
|
||||||
pubSub->setAccountData("token", "123456");
|
pubSub.start();
|
||||||
pubSub->start();
|
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 0);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 0);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 0);
|
||||||
|
|
||||||
for (auto i = 0; i < PubSubClient::MAX_LISTENS * 2; ++i)
|
for (auto i = 0; i < PubSubClient::MAX_LISTENS * 2; ++i)
|
||||||
{
|
{
|
||||||
pubSub->listenToTopic("test");
|
pubSub.listenToTopic("test");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::sleep_for(150ms);
|
std::this_thread::sleep_for(150ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 2);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 2);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
|
|
||||||
pubSub->stop();
|
pubSub.stop();
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 2);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 2);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 2);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 2);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TwitchPubSubClient, ReceivedWhisper)
|
TEST(TwitchPubSubClient, ReceivedWhisper)
|
||||||
{
|
{
|
||||||
auto pingInterval = std::chrono::seconds(1);
|
FTest pubSub("/receive-whisper", 1s);
|
||||||
const QString host("wss://127.0.0.1:9050/receive-whisper");
|
|
||||||
|
|
||||||
auto *pubSub = new PubSub(host, pingInterval);
|
pubSub.setAccountData("token", "123456");
|
||||||
pubSub->setAccountData("token", "123456");
|
pubSub.start();
|
||||||
pubSub->start();
|
|
||||||
|
|
||||||
boost::optional<PubSubWhisperMessage> oReceivedWhisper;
|
ReceivedMessage<PubSubWhisperMessage> aReceivedWhisper;
|
||||||
|
|
||||||
pubSub->signals_.whisper.received.connect(
|
pubSub.signals_.whisper.received.connect(
|
||||||
[&oReceivedWhisper](const auto &whisperMessage) {
|
[&aReceivedWhisper](const auto &whisperMessage) {
|
||||||
oReceivedWhisper = whisperMessage;
|
aReceivedWhisper = whisperMessage;
|
||||||
});
|
});
|
||||||
|
|
||||||
pubSub->listenToTopic("whispers.123456");
|
pubSub.listenToTopic("whispers.123456");
|
||||||
|
|
||||||
std::this_thread::sleep_for(150ms);
|
std::this_thread::sleep_for(150ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 3);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 3);
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 1);
|
ASSERT_EQ(pubSub.diag.listenResponses, 1);
|
||||||
|
|
||||||
ASSERT_TRUE(oReceivedWhisper);
|
ASSERT_TRUE(aReceivedWhisper);
|
||||||
|
|
||||||
auto receivedWhisper = *oReceivedWhisper;
|
ASSERT_EQ(aReceivedWhisper->body, QString("me Kappa"));
|
||||||
|
ASSERT_EQ(aReceivedWhisper->fromUserLogin, QString("pajbot"));
|
||||||
|
ASSERT_EQ(aReceivedWhisper->fromUserID, QString("82008718"));
|
||||||
|
|
||||||
ASSERT_EQ(receivedWhisper.body, QString("me Kappa"));
|
pubSub.stop();
|
||||||
ASSERT_EQ(receivedWhisper.fromUserLogin, QString("pajbot"));
|
|
||||||
ASSERT_EQ(receivedWhisper.fromUserID, QString("82008718"));
|
|
||||||
|
|
||||||
pubSub->stop();
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 1);
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TwitchPubSubClient, ModeratorActionsUserBanned)
|
TEST(TwitchPubSubClient, ModeratorActionsUserBanned)
|
||||||
{
|
{
|
||||||
auto pingInterval = std::chrono::seconds(1);
|
FTest pubSub("/moderator-actions-user-banned", 1s);
|
||||||
const QString host("wss://127.0.0.1:9050/moderator-actions-user-banned");
|
|
||||||
|
|
||||||
auto *pubSub = new PubSub(host, pingInterval);
|
pubSub.setAccountData("token", "123456");
|
||||||
pubSub->setAccountData("token", "123456");
|
pubSub.start();
|
||||||
pubSub->start();
|
|
||||||
|
|
||||||
boost::optional<BanAction> oReceivedAction;
|
ReceivedMessage<BanAction> received;
|
||||||
|
|
||||||
pubSub->signals_.moderation.userBanned.connect(
|
pubSub.signals_.moderation.userBanned.connect(
|
||||||
[&oReceivedAction](const auto &action) {
|
[&received](const auto &action) {
|
||||||
oReceivedAction = action;
|
received = action;
|
||||||
});
|
});
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 0);
|
ASSERT_EQ(pubSub.diag.listenResponses, 0);
|
||||||
|
|
||||||
pubSub->listenToTopic("chat_moderator_actions.123456.123456");
|
pubSub.listenToTopic("chat_moderator_actions.123456.123456");
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 3);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 3);
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 1);
|
ASSERT_EQ(pubSub.diag.listenResponses, 1);
|
||||||
|
|
||||||
ASSERT_TRUE(oReceivedAction);
|
ASSERT_TRUE(received);
|
||||||
|
|
||||||
auto receivedAction = *oReceivedAction;
|
|
||||||
|
|
||||||
ActionUser expectedTarget{"140114344", "1xelerate", "", QColor()};
|
ActionUser expectedTarget{"140114344", "1xelerate", "", QColor()};
|
||||||
ActionUser expectedSource{"117691339", "mm2pl", "", QColor()};
|
ActionUser expectedSource{"117691339", "mm2pl", "", QColor()};
|
||||||
|
|
||||||
ASSERT_EQ(receivedAction.reason, QString());
|
ASSERT_EQ(received->reason, QString());
|
||||||
ASSERT_EQ(receivedAction.duration, 0);
|
ASSERT_EQ(received->duration, 0);
|
||||||
ASSERT_EQ(receivedAction.target, expectedTarget);
|
ASSERT_EQ(received->target, expectedTarget);
|
||||||
ASSERT_EQ(receivedAction.source, expectedSource);
|
ASSERT_EQ(received->source, expectedSource);
|
||||||
|
|
||||||
pubSub->stop();
|
pubSub.stop();
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 1);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TwitchPubSubClient, MissingToken)
|
TEST(TwitchPubSubClient, MissingToken)
|
||||||
{
|
{
|
||||||
auto pingInterval = std::chrono::seconds(1);
|
|
||||||
// The token that's required is "xD"
|
// The token that's required is "xD"
|
||||||
const QString host("wss://127.0.0.1:9050/authentication-required");
|
FTest pubSub("/authentication-required", 1s);
|
||||||
|
|
||||||
auto *pubSub = new PubSub(host, pingInterval);
|
// pubSub.setAccountData("", "123456");
|
||||||
// pubSub->setAccountData("", "123456");
|
pubSub.start();
|
||||||
pubSub->start();
|
|
||||||
|
|
||||||
pubSub->listenToTopic("chat_moderator_actions.123456.123456");
|
pubSub.listenToTopic("chat_moderator_actions.123456.123456");
|
||||||
|
|
||||||
std::this_thread::sleep_for(150ms);
|
std::this_thread::sleep_for(150ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 2);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 2);
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 0);
|
ASSERT_EQ(pubSub.diag.listenResponses, 0);
|
||||||
ASSERT_EQ(pubSub->diag.failedListenResponses, 1);
|
ASSERT_EQ(pubSub.diag.failedListenResponses, 1);
|
||||||
|
|
||||||
pubSub->stop();
|
pubSub.stop();
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 1);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TwitchPubSubClient, WrongToken)
|
TEST(TwitchPubSubClient, WrongToken)
|
||||||
{
|
{
|
||||||
auto pingInterval = std::chrono::seconds(1);
|
|
||||||
// The token that's required is "xD"
|
// The token that's required is "xD"
|
||||||
const QString host("wss://127.0.0.1:9050/authentication-required");
|
FTest pubSub("/authentication-required", 1s);
|
||||||
|
|
||||||
auto *pubSub = new PubSub(host, pingInterval);
|
pubSub.setAccountData("wrongtoken", "123456");
|
||||||
pubSub->setAccountData("wrongtoken", "123456");
|
pubSub.start();
|
||||||
pubSub->start();
|
|
||||||
|
|
||||||
pubSub->listenToTopic("chat_moderator_actions.123456.123456");
|
pubSub.listenToTopic("chat_moderator_actions.123456.123456");
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 2);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 2);
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 0);
|
ASSERT_EQ(pubSub.diag.listenResponses, 0);
|
||||||
ASSERT_EQ(pubSub->diag.failedListenResponses, 1);
|
ASSERT_EQ(pubSub.diag.failedListenResponses, 1);
|
||||||
|
|
||||||
pubSub->stop();
|
pubSub.stop();
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 1);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TwitchPubSubClient, CorrectToken)
|
TEST(TwitchPubSubClient, CorrectToken)
|
||||||
{
|
{
|
||||||
auto pingInterval = std::chrono::seconds(1);
|
|
||||||
// The token that's required is "xD"
|
// The token that's required is "xD"
|
||||||
const QString host("wss://127.0.0.1:9050/authentication-required");
|
FTest pubSub("/authentication-required", 1s);
|
||||||
|
|
||||||
auto *pubSub = new PubSub(host, pingInterval);
|
pubSub.setAccountData("xD", "123456");
|
||||||
pubSub->setAccountData("xD", "123456");
|
pubSub.start();
|
||||||
pubSub->start();
|
|
||||||
|
|
||||||
pubSub->listenToTopic("chat_moderator_actions.123456.123456");
|
pubSub.listenToTopic("chat_moderator_actions.123456.123456");
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 2);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 2);
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 1);
|
ASSERT_EQ(pubSub.diag.listenResponses, 1);
|
||||||
ASSERT_EQ(pubSub->diag.failedListenResponses, 0);
|
ASSERT_EQ(pubSub.diag.failedListenResponses, 0);
|
||||||
|
|
||||||
pubSub->stop();
|
pubSub.stop();
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 1);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TwitchPubSubClient, AutoModMessageHeld)
|
TEST(TwitchPubSubClient, AutoModMessageHeld)
|
||||||
{
|
{
|
||||||
auto pingInterval = std::chrono::seconds(1);
|
FTest pubSub("/automod-held", 1s);
|
||||||
const QString host("wss://127.0.0.1:9050/automod-held");
|
|
||||||
|
|
||||||
auto *pubSub = new PubSub(host, pingInterval);
|
pubSub.setAccountData("xD", "123456");
|
||||||
pubSub->setAccountData("xD", "123456");
|
pubSub.start();
|
||||||
pubSub->start();
|
|
||||||
|
|
||||||
boost::optional<PubSubAutoModQueueMessage> oReceived;
|
ReceivedMessage<PubSubAutoModQueueMessage> received;
|
||||||
boost::optional<QString> oChannelID;
|
ReceivedMessage<QString> channelID;
|
||||||
|
|
||||||
pubSub->signals_.moderation.autoModMessageCaught.connect(
|
pubSub.signals_.moderation.autoModMessageCaught.connect(
|
||||||
[&](const auto &msg, const QString &channelID) {
|
[&](const auto &msg, const QString &incomingChannelID) {
|
||||||
oReceived = msg;
|
received = msg;
|
||||||
oChannelID = channelID;
|
channelID = incomingChannelID;
|
||||||
});
|
});
|
||||||
|
|
||||||
pubSub->listenToTopic("automod-queue.117166826.117166826");
|
pubSub.listenToTopic("automod-queue.117166826.117166826");
|
||||||
|
|
||||||
std::this_thread::sleep_for(50ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
ASSERT_EQ(pubSub->diag.messagesReceived, 3);
|
ASSERT_EQ(pubSub.diag.messagesReceived, 3);
|
||||||
ASSERT_EQ(pubSub->diag.listenResponses, 1);
|
ASSERT_EQ(pubSub.diag.listenResponses, 1);
|
||||||
ASSERT_EQ(pubSub->diag.failedListenResponses, 0);
|
ASSERT_EQ(pubSub.diag.failedListenResponses, 0);
|
||||||
|
|
||||||
ASSERT_TRUE(oReceived);
|
ASSERT_TRUE(received);
|
||||||
ASSERT_TRUE(oChannelID);
|
ASSERT_TRUE(channelID);
|
||||||
|
|
||||||
auto received = *oReceived;
|
|
||||||
auto channelID = *oChannelID;
|
|
||||||
|
|
||||||
ASSERT_EQ(channelID, "117166826");
|
ASSERT_EQ(channelID, "117166826");
|
||||||
ASSERT_EQ(received.messageText, "kurwa");
|
ASSERT_EQ(received->messageText, "kurwa");
|
||||||
|
|
||||||
pubSub->stop();
|
pubSub.stop();
|
||||||
|
|
||||||
ASSERT_EQ(pubSub->diag.connectionsOpened, 1);
|
ASSERT_EQ(pubSub.diag.connectionsOpened, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsClosed, 1);
|
ASSERT_EQ(pubSub.diag.connectionsClosed, 1);
|
||||||
ASSERT_EQ(pubSub->diag.connectionsFailed, 0);
|
ASSERT_EQ(pubSub.diag.connectionsFailed, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue