larra/tests/xml_stream.cpp

190 lines
6.2 KiB
C++
Raw Permalink 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>
2024-10-06 12:25:42 +00:00
#include <larra/stream.hpp>
2024-10-08 08:36:08 +00:00
#include <larra/xml_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-10-08 08:36:08 +00:00
TEST(XmlStream, ReadByOne) {
2024-09-28 19:15:31 +00:00
boost::asio::io_context context;
bool error{};
boost::asio::co_spawn(
context,
// NOLINTNEXTLINE: Safe
[&] -> boost::asio::awaitable<void> {
2024-10-08 08:36:08 +00:00
XmlStream stream{impl::MockSocket{context.get_executor(), 1}};
2024-09-28 19:15:31 +00:00
stream.AddReceivedData(kDoc);
try {
2024-10-08 08:36:08 +00:00
auto doc = co_await stream.ReadRaw(stream.next_layer());
2024-09-28 19:15:31 +00:00
auto node = doc->get_root_node();
EXPECT_EQ(node->get_name(), std::string_view{"doc"});
EXPECT_FALSE(node->has_child_text());
2024-10-08 08:36:08 +00:00
auto doc2 = co_await stream.ReadRaw(stream.next_layer());
2024-09-28 19:15:31 +00:00
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);
}
2024-10-08 08:36:08 +00:00
TEST(XmlStream, ReadAll) {
2024-09-28 19:15:31 +00:00
boost::asio::io_context context;
bool error{};
boost::asio::co_spawn(
context, // NOLINTNEXTLINE: Safe
[&] -> boost::asio::awaitable<void> {
2024-10-08 08:36:08 +00:00
XmlStream stream{impl::MockSocket{context.get_executor(), kDoc.size()}};
2024-09-28 19:15:31 +00:00
stream.AddReceivedData(kDoc);
try {
2024-10-08 08:36:08 +00:00
auto doc = co_await stream.ReadRaw(stream.next_layer());
2024-09-28 19:15:31 +00:00
auto node = doc->get_root_node();
EXPECT_EQ(node->get_name(), std::string_view{"doc"});
EXPECT_FALSE(node->has_child_text());
2024-10-08 08:36:08 +00:00
auto doc2 = co_await stream.ReadRaw(stream.next_layer());
2024-09-28 19:15:31 +00:00
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);
}
2024-10-08 08:36:08 +00:00
TEST(XmlStream, ReadAllWithEnd) {
2024-09-28 19:15:31 +00:00
boost::asio::io_context context;
bool error{};
boost::asio::co_spawn(
context, // NOLINTNEXTLINE: Safe
[&] -> boost::asio::awaitable<void> {
2024-10-08 08:36:08 +00:00
XmlStream stream{impl::MockSocket{context.get_executor(), kDoc2.size()}};
2024-09-28 19:15:31 +00:00
stream.AddReceivedData(kDoc2);
try {
2024-10-08 08:36:08 +00:00
auto doc = co_await stream.ReadRaw(stream.next_layer());
2024-09-28 19:15:31 +00:00
auto node = doc->get_root_node();
EXPECT_EQ(node->get_name(), std::string_view{"doc"});
EXPECT_FALSE(node->has_child_text());
2024-10-08 08:36:08 +00:00
auto doc2 = co_await stream.ReadRaw(stream.next_layer());
2024-09-28 19:15:31 +00:00
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);
}
2024-10-08 08:36:08 +00:00
TEST(XmlStream, ReadFeatures) {
2024-09-28 19:15:31 +00:00
boost::asio::io_context context;
bool error{};
boost::asio::co_spawn(
context, // NOLINTNEXTLINE: Safe
[&] -> boost::asio::awaitable<void> {
2024-10-08 08:36:08 +00:00
XmlStream stream{impl::MockSocket{context.get_executor(), kDoc3.size()}};
2024-09-28 19:15:31 +00:00
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");
}
};
2024-10-08 08:36:08 +00:00
TEST(XmlStream, Write) {
2024-09-28 19:15:31 +00:00
boost::asio::io_context context;
bool error{};
boost::asio::co_spawn(
context, // NOLINTNEXTLINE: Safe
[&] -> boost::asio::awaitable<void> {
2024-10-08 08:36:08 +00:00
XmlStream stream1{impl::MockSocket{context.get_executor()}};
2024-09-28 19:15:31 +00:00
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-08 08:36:08 +00:00
TEST(XmlStream, ReadOneByOne) {
2024-10-06 12:25:42 +00:00
boost::asio::io_context context;
bool error{};
boost::asio::co_spawn(
context,
// NOLINTNEXTLINE: Safe
[&] -> boost::asio::awaitable<void> {
2024-10-08 08:36:08 +00:00
XmlStream stream{impl::MockSocket{context.get_executor(), 1}};
2024-10-06 12:25:42 +00:00
stream.AddReceivedData(kDoc4);
try {
2024-10-08 08:36:08 +00:00
ServerToUserStream value = (co_await stream.ReadOne(), co_await stream.ReadOne<ServerToUserStream>());
EXPECT_EQ(value.id, "68321991947053239");
EXPECT_EQ(value.version, "1.0");
EXPECT_EQ(value.to, BareJid::Parse("test1@localhost"));
EXPECT_EQ(value.from, "localhost");
2024-10-06 12:25:42 +00:00
} 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