Fixed errors and improve roster tests
All checks were successful
PR Check / on-push-commit-check (push) Successful in 12m15s

This commit is contained in:
Ivan-lis 2024-11-18 23:04:57 +00:00
parent 7685385559
commit 54b3535ebc
7 changed files with 32 additions and 42 deletions

View file

@ -47,7 +47,4 @@ using SetBind = Set<Bind>;
using ResultBind = Result<Bind>; using ResultBind = Result<Bind>;
using IqBind = Iq<Bind>; using IqBind = Iq<Bind>;
inline auto MakeSetBind() {
return SetBind{.id = "1", .payload = Bind{}};
}
} // namespace larra::xmpp::iq } // namespace larra::xmpp::iq

View file

@ -80,7 +80,7 @@ struct Client {
auto CreateResourceBind() -> boost::asio::awaitable<void> { auto CreateResourceBind() -> boost::asio::awaitable<void> {
SPDLOG_INFO("Send IQ: Set::Bind"); SPDLOG_INFO("Send IQ: Set::Bind");
co_await this->Send(::iq::MakeSetBind()); co_await this->Send(::iq::SetBind{.id = "1", .payload = ::iq::Bind{}});
auto bind_result = co_await connection.template Read<::iq::ResultBind>(); auto bind_result = co_await connection.template Read<::iq::ResultBind>();
jid.resource = std::move(bind_result.payload.jid->resource); jid.resource = std::move(bind_result.payload.jid->resource);
@ -89,7 +89,7 @@ struct Client {
auto UpdateListOfContacts() -> boost::asio::awaitable<void> { auto UpdateListOfContacts() -> boost::asio::awaitable<void> {
SPDLOG_INFO("Send IQ: Get::Roster"); SPDLOG_INFO("Send IQ: Get::Roster");
co_await this->Send(::iq::MakeGetRoster(jid)); co_await this->Send(::iq::GetRoster{.id = "1", .from = ToString(jid), .payload = ::iq::Roster{}});
const auto roster_result = co_await connection.template Read<::iq::ResultRoster>(); const auto roster_result = co_await connection.template Read<::iq::ResultRoster>();
roster = std::move(roster_result.payload); roster = std::move(roster_result.payload);
@ -143,14 +143,15 @@ struct Challenge {
throw std::runtime_error(std::format("Invalid name {} for challenge", node->get_name())); throw std::runtime_error(std::format("Invalid name {} for challenge", node->get_name()));
} }
std::string decoded = DecodeBase64(node->get_first_child_text()->get_content()); std::string decoded = DecodeBase64(node->get_first_child_text()->get_content());
auto params = std::views::split(decoded, ',') | std::views::transform([](auto param) { auto params = std::views::split(decoded, ',') //
return std::string_view{param}; | std::views::transform([](auto param) { //
}) | return std::string_view{param}; //
std::views::transform([](std::string_view param) -> std::pair<std::string_view, std::string_view> { }) //
auto v = param.find("="); | std::views::transform([](std::string_view param) -> std::pair<std::string_view, std::string_view> { //
return {param.substr(0, v), param.substr(v + 1)}; auto v = param.find("="); //
}) | return {param.substr(0, v), param.substr(v + 1)}; //
std::ranges::to<std::unordered_map<std::string_view, std::string_view>>(); }) //
| std::ranges::to<std::unordered_map<std::string_view, std::string_view>>();
return {.body = std::move(decoded), return {.body = std::move(decoded),
.serverNonce = params.at("r"), .serverNonce = params.at("r"),
.salt = DecodeBase64(params.at("s")), .salt = DecodeBase64(params.at("s")),

View file

@ -63,7 +63,6 @@ struct BaseImplWithPayload {
auto from = element->get_attribute("from"); auto from = element->get_attribute("from");
auto to = element->get_attribute("to"); auto to = element->get_attribute("to");
using S = Serialization<PayloadType>; using S = Serialization<PayloadType>;
auto payload = element->get_first_child(S::kDefaultName); auto payload = element->get_first_child(S::kDefaultName);
if(!payload) { if(!payload) {
@ -73,8 +72,7 @@ struct BaseImplWithPayload {
if(!payload2) { if(!payload2) {
throw std::runtime_error("Invalid payload for parse Iq"); throw std::runtime_error("Invalid payload for parse Iq");
} }
return { return {.id = idNode->get_value(),
.id = idNode->get_value(),
.from = (from ? std::optional{from->get_value()} : std::nullopt), .from = (from ? std::optional{from->get_value()} : std::nullopt),
.to = (to ? std::optional{to->get_value()} : std::nullopt), .to = (to ? std::optional{to->get_value()} : std::nullopt),
.payload = S::Parse(payload2)}; .payload = S::Parse(payload2)};

View file

@ -54,9 +54,10 @@ struct FullJid {
struct BareJid { struct BareJid {
std::string username; std::string username;
std::string server; std::string server;
constexpr operator FullJid() const { constexpr operator FullJid(this auto&& self) {
return FullJid{.username = username, .server = server, .resource = ""}; return {.username = std::forward_like<decltype(self)>(self.username), .server = std::forward_like<decltype(self)>(self.server)};
} }
[[nodiscard]] static auto Parse(std::string_view jid) -> BareJid; [[nodiscard]] static auto Parse(std::string_view jid) -> BareJid;
friend auto ToString(const BareJid& jid) -> std::string; friend auto ToString(const BareJid& jid) -> std::string;

View file

@ -38,9 +38,9 @@ struct Roster {
} }
friend constexpr auto operator<<(xmlpp::Element* element, const Roster& roster) { friend constexpr auto operator<<(xmlpp::Element* element, const Roster& roster) {
element->set_attribute("xmlns", Roster::kDefaultNamespace); element->set_attribute("xmlns", Roster::kDefaultNamespace);
std::ranges::for_each(roster.items, [element](const auto& item) { for(const auto& item : roster.items) {
element->add_child_element("item")->set_attribute("jid", ToString(item)); element->add_child_element("item")->set_attribute("jid", ToString(item));
}); }
} }
[[nodiscard]] static constexpr auto Parse(xmlpp::Element* element) -> Roster { [[nodiscard]] static constexpr auto Parse(xmlpp::Element* element) -> Roster {
const auto& item_nodes = element->get_children("item"); const auto& item_nodes = element->get_children("item");
@ -69,8 +69,4 @@ using GetRoster = Get<Roster>;
using ResultRoster = Result<Roster>; using ResultRoster = Result<Roster>;
using IqRoster = Iq<Roster>; using IqRoster = Iq<Roster>;
inline auto MakeGetRoster(const FullJid& jid) {
return GetRoster{.id = "1", .from = ToString(jid), .payload = Roster{}};
}
} // namespace larra::xmpp::iq } // namespace larra::xmpp::iq

View file

@ -297,7 +297,7 @@ struct RangeToWrapper : T {
template <typename T> template <typename T>
concept LengthCalculatable = requires(const T& obj) { concept LengthCalculatable = requires(const T& obj) {
{ obj.length() } -> std::convertible_to<std::size_t>; // Checks if obj has a length() method returning a type convertible to std::size_t { obj.length() } -> std::convertible_to<std::size_t>;
} || std::convertible_to<T, std::string>; } || std::convertible_to<T, std::string>;
template <typename T> template <typename T>

View file

@ -1,17 +1,13 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <larra/jid.hpp>
#include <larra/roster.hpp> #include <larra/roster.hpp>
#include "larra/jid.hpp"
namespace larra::xmpp { namespace larra::xmpp {
TEST(Roster, SerializeAndParse) { TEST(Roster, SerializeAndParse) {
FullJid jid{.username = "test", .server = "server", .resource = "res"}; // NOLINT FullJid jid{.username = "test", .server = "server", .resource = "res"}; // NOLINT
auto roster = iq::MakeGetRoster(jid); auto roster = iq::GetRoster{.id = "1", .from = ToString(jid), .payload = iq::Roster{.items = {{"u1", "s1"}, {"u2", "s2"}, {"u3", "s3"}}}};
roster.payload.items.emplace_back("u1", "s1");
roster.payload.items.emplace_back("u2", "s2");
roster.payload.items.emplace_back("u3", "s3");
xmlpp::Document doc; xmlpp::Document doc;
auto node = doc.create_root_node("iq"); auto node = doc.create_root_node("iq");
@ -22,18 +18,19 @@ TEST(Roster, SerializeAndParse) {
ASSERT_EQ(roster.payload.items.size(), parse_res.payload.items.size()); ASSERT_EQ(roster.payload.items.size(), parse_res.payload.items.size());
for(const auto& [idx, expect_el, parsed_el] : std::views::zip(std::views::iota(0), roster.payload.items, parse_res.payload.items)) { for(const auto& [idx, expect_el, parsed_el] : std::views::zip(std::views::iota(0), roster.payload.items, parse_res.payload.items)) {
EXPECT_EQ(expect_el, parsed_el) << "Mismatched on idx: " << idx; EXPECT_EQ(expect_el, parsed_el) << "Mismatched on idx: " << idx;
// std::cerr << " " << "idx: " << idx << "; expect_el: " << expect_el << "; parsed_el: " << parsed_el << '\n';
} }
} }
static constexpr std::string_view kRosterPrintExpectedData = "Roster: [\n\tu1@s1\n\tu2@s2\n\tu3@s3\n\t]";
TEST(Roster, Print) { TEST(Roster, Print) {
FullJid jid{.username = "test", .server = "server", .resource = "res"}; // NOLINT FullJid jid{.username = "test", .server = "server", .resource = "res"}; // NOLINT
auto roster = iq::MakeGetRoster(jid); auto roster = iq::GetRoster{.id = "1", .from = ToString(jid), .payload = iq::Roster{.items = {{"u1", "s1"}, {"u2", "s2"}, {"u3", "s3"}}}};
roster.payload.items.emplace_back("u1", "s1");
roster.payload.items.emplace_back("u2", "s2");
roster.payload.items.emplace_back("u3", "s3");
EXPECT_NO_THROW({ std::cerr << "[ ] Roster payload: " << ToString(roster.payload) << '\n'; }); EXPECT_NO_THROW({
auto roster_str = ToString(roster.payload);
EXPECT_EQ(kRosterPrintExpectedData.length(), roster_str.capacity());
EXPECT_EQ(kRosterPrintExpectedData, roster_str);
});
} }
} // namespace larra::xmpp } // namespace larra::xmpp