Compare commits

..

1 commit

Author SHA1 Message Date
d88f14a66d Fixed errors and improve roster tests
All checks were successful
PR Check / on-push-commit-check (push) Successful in 11m42s
2024-11-21 22:33:43 +00:00
3 changed files with 59 additions and 11 deletions

View file

@ -80,21 +80,35 @@ struct Client {
auto CreateResourceBind() -> boost::asio::awaitable<void> {
SPDLOG_INFO("Send IQ: Set::Bind");
co_await this->Send(::iq::SetBind{.id = "1", .payload = ::iq::Bind{}});
co_await this->Send(::iq::SetBind{.id = "1", .payload = {}});
auto bind_result = co_await connection.template Read<::iq::ResultBind>();
jid.resource = std::move(bind_result.payload.jid->resource);
auto set_bind_response = co_await connection.template Read<Iq<::iq::Bind>>();
std::visit(utempl::Overloaded(
[](auto error) {
throw "Error response on IQ: Set::Bind: ''"; // TODO(unknown): Add exact error parsing
},
[&](::iq::ResultBind r) {
jid.resource = std::move(r.payload.jid->resource);
SPDLOG_INFO("Allocated resource: {}", jid.resource);
}),
set_bind_response);
co_return;
}
auto UpdateListOfContacts() -> boost::asio::awaitable<void> {
SPDLOG_INFO("Send IQ: Get::Roster");
co_await this->Send(::iq::GetRoster{.id = "1", .from = ToString(jid), .payload = ::iq::Roster{}});
co_await this->Send(::iq::GetRoster{.id = "1", .from = std::format("{}@{}", "invalid_user", jid.server), .payload = {}});
const auto roster_result = co_await connection.template Read<::iq::ResultRoster>();
roster = std::move(roster_result.payload);
SPDLOG_INFO("New roster: {}", ToString(roster));
const auto get_roster_response = co_await connection.template Read<Iq<::iq::Roster>>();
std::visit(utempl::Overloaded(
[](auto error) {
throw "Error response on IQ: Get::Roster: ''"; // TODO(unknown): Add exact error parsing
},
[&](::iq::ResultRoster r) {
roster = std::move(r.payload);
SPDLOG_INFO("New roster: {}", ToString(roster));
}),
get_roster_response);
co_return;
}

View file

@ -48,6 +48,19 @@ struct BaseImplWithPayload {
S::Serialize(element->add_child_element(S::kDefaultName, S::kPrefix), self.payload);
}
[[nodiscard]] static constexpr auto TryParse(xmlpp::Element* element) -> std::optional<BaseImplWithPayload> {
return [&] -> std::optional<BaseImplWithPayload> {
auto node = element->get_attribute("type");
if(!node) {
return std::nullopt;
}
if(node->get_value() != Name) {
return std::nullopt;
}
return Parse(element);
}();
}
[[nodiscard]] static constexpr auto Parse(xmlpp::Element* element) -> BaseImplWithPayload {
auto node = element->get_attribute("type");
if(!node) {
@ -78,6 +91,7 @@ struct BaseImplWithPayload {
.payload = S::Parse(payload2)};
}
};
static constexpr auto kGetName = "get";
template <typename Payload>

View file

@ -73,6 +73,25 @@ struct ErrorImpl : BaseError {
}
};
// Helper class to prevent parsing response stream into an expected return type if its name is a 'stream:error'
struct UnknownXmppError : BaseError {
static constexpr auto kDefaultName = "stream:error";
static constexpr std::string_view kErrorMessage = "Unknown XMPP stream error";
static constexpr auto TryParse(xmlpp::Element* element) {
return std::optional{UnknownXmppError{}};
}
static constexpr auto Parse(xmlpp::Element* element) {
return TryParse(element).value();
}
friend constexpr auto operator<<(xmlpp::Element* element, const UnknownXmppError& obj) -> void {
throw std::format("'{}' must never be written into the real stream!", kErrorMessage);
}
[[nodiscard]] constexpr auto what() const noexcept -> const char* override {
return kErrorMessage.data();
}
};
struct BadFormat : ErrorImpl<BadFormat> {};
struct BadNamespacePrefix : ErrorImpl<BadNamespacePrefix> {};
struct Conflict : ErrorImpl<Conflict> {};
@ -81,7 +100,7 @@ struct HostGone : ErrorImpl<HostGone> {};
struct HostUnknown : ErrorImpl<HostUnknown> {};
struct ImproperAdressing : ErrorImpl<ImproperAdressing> {};
struct InternalServerError : ErrorImpl<InternalServerError> {};
struct InvalidForm : ErrorImpl<InvalidForm> {};
struct InvalidFrom : ErrorImpl<InvalidFrom> {};
struct InvalidNamespace : ErrorImpl<InvalidNamespace> {};
struct InvalidXml : ErrorImpl<InvalidXml> {};
struct NotAuthorized : ErrorImpl<NotAuthorized> {};
@ -109,7 +128,7 @@ using StreamError = std::variant<error::stream::BadFormat,
error::stream::HostUnknown,
error::stream::ImproperAdressing,
error::stream::InternalServerError,
error::stream::InvalidForm,
error::stream::InvalidFrom,
error::stream::InvalidNamespace,
error::stream::InvalidXml,
error::stream::NotAuthorized,
@ -123,6 +142,7 @@ using StreamError = std::variant<error::stream::BadFormat,
error::stream::UnsupportedEncoding,
error::stream::UnsupportedFeature,
error::stream::UnsupportedStanzaType,
error::stream::UnsupportedVersion>;
error::stream::UnsupportedVersion,
error::stream::UnknownXmppError>;
} // namespace larra::xmpp