191 lines
6.1 KiB
C++
191 lines
6.1 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include <boost/asio/co_spawn.hpp>
|
|
#include <boost/asio/detached.hpp>
|
|
#include <boost/asio/ip/tcp.hpp>
|
|
#include <larra/features.hpp>
|
|
#include <larra/impl/mock_socket.hpp>
|
|
#include <larra/raw_xml_stream.hpp>
|
|
#include <larra/stream.hpp>
|
|
#include <utempl/utils.hpp>
|
|
|
|
namespace larra::xmpp {
|
|
|
|
constexpr std::string_view kDoc = "<doc></doc>\n<doc2></doc2>\n<doc3/>";
|
|
|
|
constexpr std::string_view kDoc2 = "<doc></doc>\n<doc2></doc2>";
|
|
|
|
constexpr std::string_view kDoc3 =
|
|
"<stream:features><mechanisms "
|
|
"xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>SCRAM-SHA-256</mechanism><mechanism>X-OAUTH2</"
|
|
"mechanism></mechanisms><register xmlns='http://jabber.org/features/iq-register'/></stream:features>";
|
|
|
|
constexpr std::string_view kDoc4 =
|
|
R"(<?xml version='1.0'?><stream:stream id='68321991947053239' version='1.0' xml:lang='en' xmlns:stream='http://etherx.jabber.org/streams' to='test1@localhost' from='localhost' xmlns='jabber:client'>)";
|
|
|
|
TEST(RawXmlStream, ReadByOne) {
|
|
boost::asio::io_context context;
|
|
bool error{};
|
|
|
|
boost::asio::co_spawn(
|
|
context,
|
|
// NOLINTNEXTLINE: Safe
|
|
[&] -> boost::asio::awaitable<void> {
|
|
RawXmlStream stream{impl::MockSocket{context.get_executor(), 1}};
|
|
stream.AddReceivedData(kDoc);
|
|
try {
|
|
auto doc = co_await stream.Read();
|
|
auto node = doc->get_root_node();
|
|
EXPECT_EQ(node->get_name(), std::string_view{"doc"});
|
|
EXPECT_FALSE(node->has_child_text());
|
|
auto doc2 = co_await stream.Read();
|
|
auto node2 = doc2->get_root_node();
|
|
EXPECT_EQ(node2->get_name(), std::string_view{"doc2"});
|
|
EXPECT_FALSE(node2->has_child_text());
|
|
|
|
} catch(const std::exception& err) {
|
|
SPDLOG_ERROR("{}", err.what());
|
|
error = true;
|
|
}
|
|
},
|
|
boost::asio::detached);
|
|
|
|
context.run();
|
|
EXPECT_FALSE(error);
|
|
}
|
|
|
|
TEST(RawXmlStream, ReadAll) {
|
|
boost::asio::io_context context;
|
|
bool error{};
|
|
boost::asio::co_spawn(
|
|
context, // NOLINTNEXTLINE: Safe
|
|
[&] -> boost::asio::awaitable<void> {
|
|
RawXmlStream stream{impl::MockSocket{context.get_executor(), kDoc.size()}};
|
|
stream.AddReceivedData(kDoc);
|
|
try {
|
|
auto doc = co_await stream.Read();
|
|
auto node = doc->get_root_node();
|
|
EXPECT_EQ(node->get_name(), std::string_view{"doc"});
|
|
EXPECT_FALSE(node->has_child_text());
|
|
auto doc2 = co_await stream.Read();
|
|
auto node2 = doc2->get_root_node();
|
|
EXPECT_EQ(node2->get_name(), std::string_view{"doc2"});
|
|
EXPECT_FALSE(node2->has_child_text());
|
|
|
|
} catch(const std::exception& err) {
|
|
SPDLOG_ERROR("{}", err.what());
|
|
error = true;
|
|
}
|
|
},
|
|
boost::asio::detached);
|
|
context.run();
|
|
EXPECT_FALSE(error);
|
|
}
|
|
|
|
TEST(RawXmlStream, ReadAllWithEnd) {
|
|
boost::asio::io_context context;
|
|
bool error{};
|
|
boost::asio::co_spawn(
|
|
context, // NOLINTNEXTLINE: Safe
|
|
[&] -> boost::asio::awaitable<void> {
|
|
RawXmlStream stream{impl::MockSocket{context.get_executor(), kDoc2.size()}};
|
|
stream.AddReceivedData(kDoc2);
|
|
try {
|
|
auto doc = co_await stream.Read();
|
|
auto node = doc->get_root_node();
|
|
EXPECT_EQ(node->get_name(), std::string_view{"doc"});
|
|
EXPECT_FALSE(node->has_child_text());
|
|
auto doc2 = co_await stream.Read();
|
|
auto node2 = doc2->get_root_node();
|
|
EXPECT_EQ(node2->get_name(), std::string_view{"doc2"});
|
|
EXPECT_FALSE(node2->has_child_text());
|
|
|
|
} catch(const std::exception& err) {
|
|
SPDLOG_ERROR("{}", err.what());
|
|
error = true;
|
|
}
|
|
},
|
|
boost::asio::detached);
|
|
context.run();
|
|
EXPECT_FALSE(error);
|
|
}
|
|
|
|
TEST(RawXmlStream, ReadFeatures) {
|
|
boost::asio::io_context context;
|
|
bool error{};
|
|
boost::asio::co_spawn(
|
|
context, // NOLINTNEXTLINE: Safe
|
|
[&] -> boost::asio::awaitable<void> {
|
|
RawXmlStream stream{impl::MockSocket{context.get_executor(), kDoc3.size()}};
|
|
stream.AddReceivedData(kDoc3);
|
|
try {
|
|
auto features = co_await stream.template Read<StreamFeatures>();
|
|
} catch(const std::exception& err) {
|
|
SPDLOG_ERROR("{}", err.what());
|
|
error = true;
|
|
}
|
|
},
|
|
boost::asio::detached);
|
|
context.run();
|
|
EXPECT_FALSE(error);
|
|
}
|
|
|
|
struct SomeStruct {
|
|
static constexpr auto kDefaultName = "some";
|
|
static constexpr auto kDefaultNamespace = "namespace";
|
|
static constexpr auto kPrefix = "prefix";
|
|
friend auto operator<<(xmlpp::Element* node, const SomeStruct&) {
|
|
node->add_child_text("text");
|
|
}
|
|
};
|
|
|
|
TEST(RawXmlStream, Write) {
|
|
boost::asio::io_context context;
|
|
bool error{};
|
|
boost::asio::co_spawn(
|
|
context, // NOLINTNEXTLINE: Safe
|
|
[&] -> boost::asio::awaitable<void> {
|
|
RawXmlStream stream1{impl::MockSocket{context.get_executor()}};
|
|
auto stream = std::move(stream1);
|
|
try {
|
|
co_await stream.Send(SomeStruct{});
|
|
EXPECT_EQ(stream.GetSentData(), std::string_view{"<prefix:some xmlns:prefix=\"namespace\">text</prefix:some>"});
|
|
} catch(const std::exception& err) {
|
|
SPDLOG_ERROR("{}", err.what());
|
|
error = true;
|
|
}
|
|
},
|
|
boost::asio::detached);
|
|
context.run();
|
|
EXPECT_FALSE(error);
|
|
}
|
|
|
|
TEST(RawXmlStream, ReadOneByOne) {
|
|
boost::asio::io_context context;
|
|
bool error{};
|
|
boost::asio::co_spawn(
|
|
context,
|
|
// NOLINTNEXTLINE: Safe
|
|
[&] -> boost::asio::awaitable<void> {
|
|
RawXmlStream stream{impl::MockSocket{context.get_executor(), 1}};
|
|
stream.AddReceivedData(kDoc4);
|
|
try {
|
|
auto doc = (co_await stream.ReadOne(), co_await stream.ReadOne());
|
|
auto node = doc->get_root_node();
|
|
EXPECT_TRUE(node);
|
|
if(!node) {
|
|
co_return;
|
|
}
|
|
auto stream = ServerToUserStream::Parse(node);
|
|
} catch(const std::exception& err) {
|
|
SPDLOG_ERROR("{}", err.what());
|
|
error = true;
|
|
}
|
|
},
|
|
boost::asio::detached);
|
|
|
|
context.run();
|
|
EXPECT_FALSE(error);
|
|
}
|
|
|
|
} // namespace larra::xmpp
|