larra/tests/raw_xml_stream.cpp

192 lines
6.1 KiB
C++
Raw Normal View History

2024-09-28 19:15:31 +00:00
#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>
2024-10-06 12:25:42 +00:00
#include <larra/stream.hpp>
2024-09-28 19:15:31 +00:00
#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>";
2024-10-06 12:25:42 +00:00
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'>)";
2024-09-28 19:15:31 +00:00
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);
}
2024-10-06 12:25:42 +00:00
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);
}
2024-09-28 19:15:31 +00:00
} // namespace larra::xmpp